I need to update the third row with the second row, the issue is that the entries are not consistent.
Field three has entities like so;
PLAT - final
PLAT -short
PLAT -prelim
PLAT -Reserved
PLAT -asdf
PLAT -lkjhh
etc.
I would like to update row 3 with just Plat. I don't want to write a pair for each one. So can I do a wild card?
I tried 'PLAT*' on line 5 but it didn't work.
import arcpy
fc = 'C:/Temp/permits.gdb/test'
assignName = {"BP" : "BuildingPermit", "FMEA" : "FEMA_LOMAR", 'PLAT*': "Sub"}
#fields = ["OBJECTID", "Type", "Type2"]
print(assignName)
cursor = arcpy.da.UpdateCursor(fc,["OBJECTID", "Type", "Type2"])
for row in cursor:
if row[1] in assignName:
print (assignName[row[1]])
row[2] = assignName[row[1]]
cursor.updateRow(row)
Solved! Go to Solution.
your line :
if row[1] in assignName:
is making it skip the rows (the Plats) that are not in the assignName dictionary so its not updating them.
Remove that line and include your "field1" in the cursor fields if you want row[2] to default to field's value if it is not in the dictionary.
cursor = arcpy.da.UpdateCursor(fc,["OBJECTID", "Type", "Type2", "field1"])
for row in cursor:
print (f'checking: {row[1]}')
row[2] = assignName['PLAT'] if row[1] in plats_list else assignName.get(row[1], row[3])
cursor.updateRow(row)
Wildcards are not allowed for dictionary keys. You could make a list of all PLATS and check if the value is in the list and assign Plat. Distinct list are easy to make with SearchCursors (where you could use the wildcard in the filter) so you can automate it.
plats_list = ['PLAT - final', 'PLAT -short', 'PLAT -prelim', 'PLAT -Reserved', 'PLAT -asdf', 'PLAT -lkjhh', ... ]
row[2] = assignName['PLAT'] if row[1] in plats_list else assignName.get(row[1])
or, if the three items in the dictionary are the only available choices, have 'Sub' as the default return.
assignName = {"BP" : "BuildingPermit", "FMEA" : "FEMA_LOMAR"}
row[2] = assignName.get(row[1], 'Sub')
or you can resort to regex but I don't think you need to take it that far.
Thanks for the reply, really appreciate it.
That explains why I didn't find anything about wildcards in Dictionaries.
I have added your suggestion but field "Type2" doesn't get populated with "Plat".
import arcpy
fc = 'C:/Temp/permits.gdb/test'
assignName = {"BP" : "BuildingPermit", "FMEA" : "FEMA_LOMAR", 'PLAT*': "Sub"}
#fields = ["OBJECTID", "Type", "Type2"]
#print(assignName)
plats_list = ['PLAT - Preliminary' ,'PLAT - Final', 'PLAT - Short']
cursor = arcpy.da.UpdateCursor(fc,["OBJECTID", "Type", "Type2"])
for row in cursor:
if row[1] in assignName:
print (assignName[row[1]])
row[2] = assignName['PLAT'] if row[1] in plats_list else assignName.get(row[1])
cursor.updateRow(row)
Try removing the asterisk in line 5.
I'd be careful with using dictionary.get() here. If it doesn't find the specified key, it will return None by default, which will remove the value from the field. I don't think that is intended behavior. Instead, I'd do a try-except. Didn't see you were updating another field, where None values don't mean data loss. I'd still do it with a try-except to get a printout of the erroneous rows, if any.
Also, row is a tuple, which is immutable, so assigning to row[2] will raise an exception. Nope, I was thinking of SearchCursor. UpdateCursor returns a list. Thanks @Anonymous User for the headsup.
import arcpy
fc = 'C:/Temp/permits.gdb/test'
assignName = {"BP" : "BuildingPermit", "FMEA" : "FEMA_LOMAR", 'PLAT': "Plat"}
with arcpy.da.UpdateCursor(fc,["OBJECTID", "Type", "Type2"]) as cursor:
for oid, t, t2 in cursor:
if t is None: # skip is no Type value
continue
if 'PLAT' in t: # Type == 'PLAT*'? -> Type = 'PLAT'
t = 'PLAT'
try:
t2 = assignName[t]
except KeyError:
print(f'KeyError for OBJECTID {oid}: Can't find {t} in assignName')
t2 = None
cursor.updateRow([oid, t, t2])
you still have the asterisks in your dictionary: 'Plat*'
assignName = {"BP" : "BuildingPermit", "FMEA" : "FEMA_LOMAR", 'PLAT*': "Sub"}
## Should be
assignName = {"BP" : "BuildingPermit", "FMEA" : "FEMA_LOMAR", 'PLAT': "Sub"}
Jeff, Sorry for the delay.
I did remove the "*", after I posted my response but still line 14 won't update the row with the plats_list.
Both fields are text fields.
I've been trying to figure it out but I can't seem to. Logically line 14 makes sense.
Also looking at the data there seems to be some blanks in row 1 "Type" field and if that is the case I would like to update row[2] "Type2" with with field1. Sorry I didn't realize this until I was looking into the Type field to see why line 14 was not being updated. If I can get pasted line 14 not passing the plat_list I can figure out how to update "Type" if "Type" field is empty.
ObjectID | Type | field1 | Type2 |
1 | BP | Permit | BuildingPermit |
2 | FEMA | FEMA_LOMARs | |
3 | PLAT - Preliminary | Sub | PLAT |
4 | Sub | PLAT | |
5 | Floodway | FEMA_Floodway |
import arcpy
fc = 'C:/Temp/permits.gdb/test'
assignName = {"BP" : "BuildingPermit", "FMEA" : "FEMA_LOMAR", 'PLAT': "Sub"}
#fields = ["OBJECTID", "Type", "Type2"]
#print(assignName)
plats_list = ['PLAT - Preliminary' ,'PLAT - Final', 'PLAT - Short']
cursor = arcpy.da.UpdateCursor(fc,["OBJECTID", "Type", "Type2"])
for row in cursor:
if row[1] in assignName:
print (assignName[row[1]])
row[2] = assignName['PLAT'] if row[1] in plats_list else assignName.get(row[1])
cursor.updateRow(row)
your line :
if row[1] in assignName:
is making it skip the rows (the Plats) that are not in the assignName dictionary so its not updating them.
Remove that line and include your "field1" in the cursor fields if you want row[2] to default to field's value if it is not in the dictionary.
cursor = arcpy.da.UpdateCursor(fc,["OBJECTID", "Type", "Type2", "field1"])
for row in cursor:
print (f'checking: {row[1]}')
row[2] = assignName['PLAT'] if row[1] in plats_list else assignName.get(row[1], row[3])
cursor.updateRow(row)
man, totally over looked that one.
Got it to work with. Thanks for all the help!
for row in cursor:
print (f'checking: {row[1]}')
row[2] = 'PLAT' if row[1] in plats_list else assignName.get(row[1], row[3])
cursor.updateRow(row)