'for a in b.layers: The object is not iterable
I am trying to list all the feature services using the below code,
from arcgis.gis import GIS
gis = GIS(url='https://pythonapi.playground.esri.com/portal', username='arcgis_python', password='amazing_arcgis_123')
items = gis.content.search(query="", item_type="Feature Service")
some_list = []
for b in items:
print(b.layers)
print(b)
for a in b.layers:
if a.properties['name'] == 'WETTBEWERBER':
some_list.append(a)
but I get this error, what am I doing wrong ?? Any insights will be helpful.
Traceback (most recent call last):
File "C:/Users/PycharmProjects/untitled/Test/Test maps.py", line 14, in <module>
for a in b.layers:
TypeError: 'NoneType' object is not iterable
I get the printed results as follows, but if I take one of the printed result URLs and tried to get that layer by changing the name according to the printed URL, I do not get any results.
F:\ArcGISPro\bin\Python\envs\arcgispro-py3\python.exe "C:/Users/PycharmProjects/untitled/Test/Test maps.py"
[<FeatureLayer url:"https://maps.com/server/rest/services/Hosted/sd/FeatureServer/0">]
<Item title:"sd" type:Feature Layer Collection owner:dafsa>
[<FeatureLayer url:"https://maps.com/server/rest/services/Hosted/CC/FeatureServer/0">]
<Item title:"CC" type:Feature Layer Collection owner:sajd57d>
[<FeatureLayer url:"https://maps.com/server/rest/services/MD/FeatureServer/0">]
<Item title:"MD" type:Feature Layer Collection owner:dasjc6>
[<FeatureLayer url:"https://maps.com/server/rest/services/Hosted/ring/FeatureServer/0">]
<Item title:"ring" type:Feature Layer Collection owner:dashk56>
For example, if I take the first URL and open my portal I can see the Feature containing a layer with its name 'WETTBEWERBER' but if the results do not show anything.
Solution 1:[1]
I suspect one or more of the items does not have layers, which would cause this error. You should try checking and skipping those items.
for b in [item for item in items if item.layers is not None]:
for a in b.layers:
if a.properties['name'] == 'WETTBEWERBER':
some_list.append(a)
I have written an example to illustrate the issue:
from dataclasses import dataclass
@dataclass
class Item:
name: str
layers: list
items = [Item("a", None), Item("b", ["l1", "l2"])]
for item in items:
for layer in item.layers:
print(layer)
Here, we get the error TypeError: 'NoneType' object is not iterable because one of the items have None for property layers. The correction is to skip those.
from dataclasses import dataclass
@dataclass
class Item:
name: str
layers: list
items = [Item("a", None), Item("b", ["l1", "l2"])]
for item in [item for item in items if item.layers is not None]:
for layer in item.layers:
print(layer)
yielding:
l1
l2
Also, as @aaron correctly points out, for a in b.layers or () or for a in b.layers or [] work too. They are even more terse, and fine in this case. In some cases, being explicit with a None check is important, but not so much here.
for item in items:
for layer in item.layers or []:
print(layer)
Solution 2:[2]
You could use
some_list = [[a for a in b.layers if a.properties['name'] == 'WETTBEWERBER'] \
for b in items if b.layers]
Test using this logic:
from dataclasses import dataclass
@dataclass
class Item:
st:str
layers:list
prop1 = {"properties":{
"name" : "l1"
}}
prop2 = {"properties":{
"name" : "l1"
}}
prop3 = {"properties":{
"name" : "l3"
}}
items = [Item('a', None),Item('b', [prop1]),Item('c',[prop2]),Item('d', None),Item('e', [prop3])]
lst = [[a for a in b.layers if a['properties']['name'] == 'l1'] \
for b in items if b.layers]
print(lst)
Alternatively, you could just add -> if b.layers is Not None after for b in items
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | |
| Solution 2 | Bane |
