Select to view content in your preferred language

loop terminates

2162
13
Jump to solution
09-21-2017 03:28 AM
TomaszChojnacki
New Contributor

Hello,

I am trying to perform some editing on features that have the same attribute value  as features of a different feature class. So I tried this:

 

field0 = 'SKMS_tor'
field1 = 'SKMS'
cursor0 = arcpy.da.SearchCursor(fc0, field0)
cursor1 = arcpy.da.SearchCursor(fc1, field1)

for row0 in cursor0:
    for row1 in cursor1:

        if row0 == row1:

            do do editing

        else:

            skip editing

 

I works, but only for the first round. Then it stops and does not proceed to the second feature in the feature class. Not sure what is wrong with this script.

 

I tested the same syntax on a different example:

 

q = ['a1', 'a2', 'a3']
w = ['a3', 'a1', 'b2']
for x in q:
    for y in w:
        if x == y:
            print x, " YES ", y
        else:
            print x, " NO ", y

 

and it works fine.

 

To my novice eye there is no difference in both scripts except the use arcpy.da.SearchCursor(). Can this be a problem? if not, what else?

 

Thanks for help.

0 Kudos
13 Replies
JoeBorgione
MVP Emeritus

bixb0012‌ ; thanks for providing the lesson in nested cursors.  That just went into my PythonSnipetss folder for future reference.

That should just about do it....
JoshuaBixby
MVP Esteemed Contributor

I was just focused on making the error go away.  As others pointed out in the comments, nesting cursors can lead to some big performance problems, and there may be other, better ways of accomplishing the work.

JoeBorgione
MVP Emeritus

Yep-  just like it as an example; I need to figure out the whole dictionary thing.....

That should just about do it....
0 Kudos
ClintonDow1
Occasional Contributor II

For a bit of context, the reason this happens is because the data access (.da) cursors are implemented as iterators which by design only allow one 'pass' and will then raise StopIteration exceptions on subsequent calls. If you want to repeatedly access the collection, or access items within the collection via an index, you can cast the iterator into a list. The .reset() method also works for multiple passes as Joshua has suggested but does not allow for indexing. The list approach is only viable if the data set you are working with is smaller than the amount of available RAM, so for larger data sets the iterator is necessary to feed the data 'piece by piece' into the script, so depending on the circumstances either approach has strengths and weaknesses.