Update Cursor from directory list

668
7
Jump to solution
08-19-2022 10:40 AM
2Quiker
Occasional Contributor II

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)

 

0 Kudos
1 Solution

Accepted Solutions
by Anonymous User
Not applicable

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)

 

View solution in original post

0 Kudos
7 Replies
by Anonymous User
Not applicable

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.

2Quiker
Occasional Contributor II

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)

 

0 Kudos
JohannesLindner
MVP Frequent Contributor

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

 

 

 


Have a great day!
Johannes
0 Kudos
by Anonymous User
Not applicable

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"}
0 Kudos
2Quiker
Occasional Contributor II

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.

 

ObjectIDTypefield1Type2
1BPPermitBuildingPermit
2FEMA FEMA_LOMARs
3PLAT - PreliminarySubPLAT
4Sub PLAT
5 FloodwayFEMA_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)

 

 

 

 

0 Kudos
by Anonymous User
Not applicable

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)

 

0 Kudos
2Quiker
Occasional Contributor II

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)

 

 

0 Kudos