Select to view content in your preferred language

arcpy.da.UpdateCursor use variable as field index?

3436
2
Jump to solution
02-27-2013 10:52 AM
ErikMartin
Frequent Contributor
I'm working with an arcpy data access update cursor with a lot of fields that have an old/new pattern (e.g. oldField1, newField1, oldField2, newField2, etc.  I have a very simple operation I'd like to do -- calculate the newField = oldField for each pair.   I know I could use CalculateField_management, which is actually what I had been doing previously.  But there are conflicting reports as to which is faster -- da.UpdateCursor or CalculateField.  I am trying to optimize speed, so I want to try this out. 

The root of my question: is there a way to use a variable instead of the list index in a da cursor.  Specifically:

import arcpy FC = "C:\\data\\test.gdb\\test"  fields = ["newField1", "oldField1", "newField2", "oldField2", "newField3", "oldField3", .... "newFieldn", "oldFieldn"]  #There are actually a lot more fields in this same new/old pattern  with arcpy.da.UpdateCursor(FC, fields) as rows:     i = 0     for row in rows:         j = i + 1         row = row  #simply setting the new value = old value for each old/new pair, but get "list index out of range" error  i = i + 1


I know I could take the actual index for each (eg row[0] = row[1], then row[2] = row[3] the next time, etc) but that would be messy with so many fields.

With the old cursors, I could have done something like the following, but the old cursors are definitely slower than CalculateField_management, so this is not worth pursuing: 

baseFieldNameList = ["Field1", "Field2", "Field3", ...  "Fieldn") rows = arcpy.UpdateCursor for field in baseFieldNameList:     newField = "new" + field     oldField = "old" + field     oldValue = row.getValue(oldField)     row.setValue(newField, oldValue)     rows.updateRow del rows, row


Any suggestions, workarounds, or input would be much appreciated.

Thanks,
-Erik
Tags (2)
0 Kudos
1 Solution

Accepted Solutions
MathewCoyle
Honored Contributor
You are getting an index error because you never reset your index back to 0 for the next row. This example should get you a little further.
with arcpy.da.UpdateCursor(FC, fields) as rows:     for row in rows:         i = 0         while i < len(fields):  #for field in fields:             row = row[i + 1]             i += 2         rows.updateRow(row)

View solution in original post

0 Kudos
2 Replies
MathewCoyle
Honored Contributor
You are getting an index error because you never reset your index back to 0 for the next row. This example should get you a little further.
with arcpy.da.UpdateCursor(FC, fields) as rows:     for row in rows:         i = 0         while i < len(fields):  #for field in fields:             row = row[i + 1]             i += 2         rows.updateRow(row)
0 Kudos
ErikMartin
Frequent Contributor
Thanks Matthew... your edited solution worked.  The two pieces I needed to change were resetting the index back to 0 for each row and using the while loop instead of the for loop.  As I'm interpreting this, the problem with the for loop would be that it was still trying to advance by two fields even for the last field, when of course there are no fields after the last field (using the for loop even with the index set to 0 for each row still results in a "list index out of range" error.). 

Also, for the record, the data access cursor was far faster than the field calculator in my case with 51 pairs of fields & 4000 records.  The data access cursor took 1 second.  The field calculator took 73 seconds... a much bigger difference than I expected and really significant for a web application (this is feeding an asynchronous GP service).  Thanks for the help!
-Erik
0 Kudos