I am trying to use arcpy.da.UpdateCursor to find and replace old values in a field with new values. I have made it work but I will ended up with an ridiculously lard if\elif statement (notice below that I stopped after the first 2 items in the list). I would like to avoid this by iterating through both list to update the field. I have tried without any luck. Any suggestions? Code is attached.
Assuming the mapping between the two life cycle status lists is one to one based on position in the list, the following will work:
import arcpy
fc = r'G:\pworks\assetmanagement\Local Gov Info Model\Wastewater\Inputs\Valve_Schema.gdb\SControlValve'
LifeCycleStatus1 = ["ABN", "ACT","AB","CHGORD","DEM","INA","OTH","PRP","RMV","UNK","FV", "FD"]
LifeCycleStatus2 = ["Abandoned","Active","As Built","Change Order","Demolished","Inactive","Other","Proposed","Removed","Unknown","Field Verification Required","Future Development"]
try:
cursor = arcpy.da.UpdateCursor(fc, ["LIFECYCLESTATUS"])
for row in cursor:
row[0] = LifeCycleStatus2[LifeCycleStatus1.index(row[0])]
cursor.updateRow(row)
del row
del cursor
except RuntimeError:
pass
Please remember to post code as ASCII text (formatted appropriately), so that those who would help you don't need to retype your code.
- V
Vince Angelo thanks for the heads up! How do I embed the code like Joshua Bixby did?
Click on the three dots above:
Click on the resulting More button and choose Syntax highlighter. Pick the language of choice, and paste your code in the window. Click Ok button at the bottom of the window...
To use a dictionary instead of a list (assuming the mapping between your two lists), something like this should also work:
import arcpy
fc = r'G:\pworks\assetmanagement\Local Gov Info Model\Wastewater\Inputs\Valve_Schema.gdb\SControlValve'
LCStatus = {
'ABN': 'Abandoned',
'ACT': 'Active',
'AB': 'As Built',
'CHGORD': 'Change Order',
'DEM': 'Demolished',
'INA': 'Inactive',
'OTH': 'Other',
'PRP': 'Proposed',
'RMV': 'Removed',
'UNK': 'Unknown',
'FV': 'Field Verification Required',
'FD': 'Future Development'
}
try:
cursor = arcpy.da.UpdateCursor(fc, ["LIFECYCLESTATUS"])
for row in cursor:
row[0] = LCStatus[row[0]]
cursor.updateRow(row)
del row
del cursor
except RuntimeError:
pass
Thanks for all the responses! Right after I posted this I figured it out how to do it this way. Any suggestions on adding an elif statement that will tell the user if there are any values in the field that are not in the list? Example: "ANB" instead of "ABN"
import arcpy
# My Feature Class that I want to use
fc = arcpy.GetParameterAsText(0)
# My List of old and new values
LifeCycleStatus1 = ["ABN", "ACT","AB","CHGORD","DEM","INA","OTH","PRP","RMV","UNK","FV", "FD"]
LifeCycleStatus2 = ["Abandoned","Active","As Built","Change Order","Demolished","Inactive","Other","Proposed","Removed","Unknown","Field Verification Required","Future Development"]
try:
i=0
for life in LifeCycleStatus1:
cursor = arcpy.da.UpdateCursor(fc, ["LIFECYCLESTATUS"])
for row in cursor:
if row[0] == LifeCycleStatus1[i]:
row[0] = LifeCycleStatus2[i]
cursor.updateRow(row)
i+=1
except RuntimeError:
pass
#logic:
if row[0] in listname:
do something
elif row[0] in listname2:
do something else
else:
print 'Not in either list...'
For the dictionary approach, a check would be something like:
for row in cursor:
if if row[0] not in LCStatus.keys():
# print error message and keep original value
print "{} not in list".format(row[0])
else: # update value
row[0] = LCStatus[row[0]]
cursor.updateRow(row)
I notice in your second code posting, you are running multiple update cursor loops, once for each item in your list (line 12). With either the indexing solution from Joshua or the dictionary solution, only a single pass with an update cursor is needed and is more efficient.