Using the older arcpy.SearchCursor, the next() method would return Nothing once the last record had been passed.

Using the newer arcpy.da.SearchCursor, I'm finding that the next() method crashes the script if there are no more records. To illustrate:

import arcpy
fc = "C:\Program Files (x86)\ArcGIS\Desktop10.2\ArcGlobeData\continent.shp"
fields = ["CONTINENT"]
where = "CONTINENT = 'Asia'"
with arcpy.da.SearchCursor(fc, fields, where) as cursor:
    for i in range(0,5):
        row = cursor.next()
        print row

There is only one record in the cursor, so the first time it iterates the name is printed. But the second iteration throws a StopIteration error.

How should we use next() with arcpy.da.SearchCursor?

  • 1
    This is more a generic Python question that it is GIS-specific. I'm sorry this tripped you up at first, but it's behaving exactly like any reasonably designed API in Python would with regards to the iterator protocol. – Jason Scheirer May 1 '14 at 23:14
  • The line between spatial analysis and programming is very thin. – nickves May 1 '14 at 23:20
  • 1
    @JasonScheirer maybe - but I didn't find anything when searching on arcpy.da.SearchCursor and next. I'm not an expert Python programmer so I didn't know to look up Python Iterator Protocol, etc. At least now it's available if someone searches on those keywords – Stephen Lead May 1 '14 at 23:29

I can't see this documented in the Esri help files, so I'm entering it here for posterity.

According to Jason Scheirer from the Esri ArcPy team this is the intended behaviour (original Esri forums post):

The .next() method raises an error by design: it follows to the letter the Python Iterator Protocol, which requires the .next() method on an object to raise a StopIteration exception when it is exhausted.

The suggested approach is to use a for iterator on the cursor, ie without using the next() method at all:

with arcpy.da.SearchCursor(fc, fields) as cursor:
    for row in cursor:

In my case I wanted to perform an action when there was no row - I found that a Try, Except block worked well:

with arcpy.da.SearchCursor(fc, fields, where) as cursor:
        row = cursor.next()
    except StopIteration:
        print("No rows")
        print("something else went wrong")
|improve this answer|||||
  • just out of curiosity, what type is row after the final entry? – nickves May 1 '14 at 23:12
  • @nickves: It's still a list. – Jason Scheirer May 1 '14 at 23:13
  • 2
    I really wouldn't call using a for loop a workaround, I'd call it the expected behavior. – Jason Scheirer May 1 '14 at 23:14
  • @JasonScheirer fair enough - it was a workaround for what I was trying to do, but I agree in most cases it's better to use the for loop. I've modified the answer – Stephen Lead May 1 '14 at 23:21
  • 2
    @nickves actually I don't think that's correct - the cursor doesn't have a length property – Stephen Lead May 1 '14 at 23:28

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.