1

I am trying to populate a unique identifier field "STD_ID" using arcpy.da.UpdateCursor. The identifier would be an iterative 1,2,3 and would reset the iteration based on region ID in which the polygon is located "RBSB_ID2"

My problem is I can't figure out how to reference the next row to restart the iteration. I updated the for loop to include cursor.next(), the error is now that I never started the iteration.

#call stands layer and define variables 
stands = "F:/ArcGIS/Data/ForestPlanning.gdb/NYC_Stands"
rbsb_std = ('RBSB_ID2', 'STD_ID')

#define iteration.
iteration = 0

#create cursor for Stand IDs using arcpy.da.UpdateCursor

with arcpy.da.UpdateCursor(stands, rbsb_std) as cursor:
for row in cursor:
    try:
        next_row = cursor.next() 
    except StopIteration:
        next_row = row 
    if row[0] != next_row[0]:
        row[1] = 1
    else:
        row[1] = iteration + 1
        iteration = iteration + 1
    cursor.updateRow(row)

Any ideas on how to fix this?

  • I just edited the code to reflect toslunds original answer.

In response to the desired output ... assume

RBSB_ID2 = [100023, 100023, 100023, 100144, 100144, 1000144, 1000144, 1001512, 1001512]

#The output for 'STD_ID' would be: 

STD_ID = [1, 2, 3, 1, 2, 3, 4, 1, 2]

#The next step would be to convert to STD_ID to a string & later convert to something like 

#[001, 002, 003, 001 ...] and then later concatenate with the RBSB_ID to 
#create a unique id for each row that links RBSB_ID2 with STD_ID.  

#RBSB_STD_ID = [100023001, 100023002, 100023003, 100144001, ...]
  • You would need to sort your data first, otherwise considering the next/previous value is not reliable. – JGH May 29 '18 at 17:08
  • It is usually easier to consider the previous value rather than the next one. If the current value is different than the previous one, restart the sequence – JGH May 29 '18 at 17:09
  • thank you. I was looking into that as well. Please see revised edits, it may provide some clarity – gfalco May 29 '18 at 18:50
1

Now that I see your edit I'll propose a shorter way to get what you want, inspired by this post. This new code will give you the desired end result, a text field with a unique id made by appending a new number with padded zeroes.

d= {}
with arcpy.da.UpdateCursor(stands, rbsb_std) as cursor:
    for row in cursor:
        if row[0] in d:
            d[row[0]]+=1
        else:
            d[row[0]]=1
        #note that row[1] is now a string field!
        row[1] = str(row[0]) + str(d[row[0]]).zfill(2)
        cursor.updateRow(row)

I'll leave the bit about the.next method but I believe the above code is much clearer. To access values for the next row you can use the python built in function .next(). Just tested this with python 3.

rbsb_std = ['RBSB_ID2', 'STD_ID']
stands = "F:/ArcGIS/Data/ForestPlanning.gdb/NYC_Stands"

with arcpy.da.UpdateCursor(stands, rbsb_std) as cursor::
    for row in cursor:
        #not sure exactly what you are testing for so I left out the if
        #statement.  But this is an example of accessing the next value
        print(row[0] == cursor.next()[0]) 
        #Make sure to call the .updateRow() method inside the
        #for loop as below
        row[0] = 'some value'
        cursor.updateRow(row)
  • Thank you toslund. So this is helpful.. I've been playing around and I think I am getting closer using cursor.next as you described. I will edit now and maybe you can take a second look. I'll add info on the desired result as well. – gfalco May 29 '18 at 18:35
  • I updated my answer to reflect your edits. Hope it helps! – toslund May 29 '18 at 20:02

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