4

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?

3
  • 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. Commented May 1, 2014 at 23:14
  • The line between spatial analysis and programming is very thin.
    – nickves
    Commented May 1, 2014 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 Commented May 1, 2014 at 23:29

1 Answer 1

4

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:
    try:
        row = cursor.next()
        print(row)
    except StopIteration:
        print("No rows")
    except:
        print("something else went wrong")
11
  • just out of curiosity, what type is row after the final entry?
    – nickves
    Commented May 1, 2014 at 23:12
  • @nickves: It's still a list. Commented May 1, 2014 at 23:13
  • 2
    I really wouldn't call using a for loop a workaround, I'd call it the expected behavior. Commented May 1, 2014 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 Commented May 1, 2014 at 23:21
  • 2
    @nickves actually I don't think that's correct - the cursor doesn't have a length property Commented May 1, 2014 at 23:28

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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