7

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()?

  • 3
    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... :) – Hornbydd Sep 10 '16 at 18:56
  • 3
    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 '16 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 '16 at 19:32
9

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)
8

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')]
  • 2
    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. – Hornbydd Sep 12 '16 at 11:33
  • @Hornbydd I appreciate the feedback. Post edited to include your comments. – Aaron Sep 13 '16 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? – gm70560 Sep 13 '16 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 '16 at 17:58
-1

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.

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.