Counting in for-loop using ArcPy Cursor?

When using the UpdateCursor, is there a "built-in" way to count within the loop?

In the moment I am using a variable i and add 1 after each iteration:

cur = arcpy.da.UpdateCursor("points.shp","ID1")
i = 0
for row in cur:
row[0] = i
cur.updateRow(row)
i = i +1


Is there a smarter way, something like row.count()?

• Personally I prefer your approach as it stands. It's clear what i is and where it's value is coming from. In my opinion making your code easy to read is as important as making it smart. I find the terse "pythonic" way of doing things is often very difficult to unravel especially list comprehension, they really blow my mind... :) Sep 10, 2016 at 18:56
• I agree with @Hornbydd, especially where you have juniors in the office that don't know python well who may need to make alterations to your code in the future.
– Midavalo
Sep 10, 2016 at 19:09
• I think that if you want to use Python, you need to learn it, at least a little bit... Python is not only ArcPy and the concept of list comprehension is basic and easy to understand if you know the for loops.
– gene
Sep 10, 2016 at 19:32

In theory (because I don't know arcpy), simply use the standard function enumerate (GeoNet: Enumeration of a cursor)

for i, row in enumerate(cur):
row[0] = i
cur.updateRow(row)


The easiest option would be to reference the OID in the attributes using the OID@ token in a SearchCursor.

import arcpy

shp = r'X:\path\to\your\shapefile.shp'

with arcpy.da.SearchCursor(shp, ["OID@", "some_field"]) as cursor:
for row in cursor:
print row


Alternatively, building on gene's answer, Python's built-in enumerate function can make a clean workflow out of this.

import arcpy

shp = r'X:\path\to\your\shapefile.shp'

with arcpy.da.SearchCursor(shp, "some_field") as cursor:
for i, row in enumerate(cursor, start = 1):
print i, row


Note that enumerate' creates a tuple of a count and the iterable value. To highlight the fuctionality (documentation):

>>> seasons = ['Spring', 'Summer', 'Fall', 'Winter']
>>> list(enumerate(seasons))
[(0, 'Spring'), (1, 'Summer'), (2, 'Fall'), (3, 'Winter')]
>>> list(enumerate(seasons, start=1))
[(1, 'Spring'), (2, 'Summer'), (3, 'Fall'), (4, 'Winter')]

• Just been having a play with the enumerate() function as I have never used it before. Just wanted to emphasise to other forum readers that it is an index value of what ever is being enumerated and not the ObjectID of the row. Maybe obvious to harden python programmers but I initially thought it was generating row ID's. So if one was going to do some sort of quality control test of index count = ObjectID that won't work. Sep 12, 2016 at 11:33
• @Hornbydd I appreciate the feedback. Post edited to include your comments.
– Aaron
Sep 13, 2016 at 0:42
• The OID route: what happens if objects have been deleted? Wouldn't that return an incorrect count compared to the actual iterations made in the search cursor loop? Sep 13, 2016 at 17:51
• @gm70560 That would be one limitation of the OID approach and worth keeping in mind. enumerate would be the go to method in the case of deleted features/rows.
– Aaron
Sep 13, 2016 at 17:58

You can use arcpy.GetCount_management() instead of having a loop. In your case it will be:

i = arcpy.GetCount_management("points.shp").getOutput(0)
`

And then you can loop through your shp file i times.