For Loop and Python String format()

343
13
Jump to solution
03-25-2020 08:10 AM
NataliaGutierrez1
New Contributor III

Hello,

I am trying to use UpdateCursor to update a field value by evaluating the value of another field. I have to do this in about 70 feature classes. For this reason I am using For Loop as well.

This is the script:

import arcpy

arcpy.env.workspace = r"D:\APRX_MXDS\USA_Parcels_2019_Project\Test.gdb"
arcpy.env.overwriteOutput = True

List_dissolve_fc = arcpy.ListFeatureClasses("*Dissolve") # get a list of feature classes that end with "Dissolve"

fields = ["CO_NO", "COUNTY_NAME"] # List of fields in test.gdb

for fc in List_dissolve_fc: # Loop through each feature class in the list
with arcpy.da.UpdateCursor(fc, fields) as cursor: # Loop through each feature
for row in cursor:
if (row[1] == "{}".format(fc[:-17])): # if COUNTY_NAME equals the name of the feature class without the last 17 characters, assign 74 to field CO_NO
row[0] = 11
elif (row[1] == "{}".format(fc[:-17])):
row[0] = 12
elif (row[1] == "{}".format(fc[:-17])):
row[0] = 13
elif (row[1] == "{}".format(fc[:-17])):
row[0] = 14
elif (row[1] == "{}".format(fc[:-17])):
row[0] = 15
elif (row[1] == "{}".format(fc[:-17])):
row[0] = 16
elif (row[1] == "{}".format(fc[:-17])):
row[0] = 17
elif (row[1] == "{}".format(fc[:-17])):
row[0] = 18
elif (row[1] == "{}".format(fc[:-17])):
row[0] = 19
elif (row[1] == "{}".format(fc[:-17])):
row[0] = 20
elif (row[1] == "{}".format(fc[:-17])):
row[0] = 21
elif (row[1] == "{}".format(fc[:-17])):
row[0] = 22
elif (row[1] == "{}".format(fc[:-17])):
row[0] = 23
elif (row[1] == "{}".format(fc[:-17])):
row[0] = 24
elif (row[1] == "{}".format(fc[:-17])):
row[0] = 25
elif (row[1] == "{}".format(fc[:-17])):
row[0] = 26
elif (row[1] == "{}".format(fc[:-17])):
row[0] = 27
elif (row[1] == "{}".format(fc[:-17])):
row[0] = 28
elif (row[1] == "{}".format(fc[:-17])):
row[0] = 29
elif (row[1] == "{}".format(fc[:-17])):
row[0] = 30
elif (row[1] == "{}".format(fc[:-17])):
row[0] = 31
elif (row[1] == "{}".format(fc[:-17])):
row[0] = 32
elif (row[1] == "{}".format(fc[:-17])):
row[0] = 33
elif (row[1] == "{}".format(fc[:-17])):
row[0] = 34
elif (row[1] == "{}".format(fc[:-17])):
row[0] = 35
elif (row[1] == "{}".format(fc[:-17])):
row[0] = 36
elif (row[1] == "{}".format(fc[:-17])):
row[0] = 37
elif (row[1] == "{}".format(fc[:-17])):
row[0] = 38
elif (row[1] == "{}".format(fc[:-17])):
row[0] = 39
elif (row[1] == "{}".format(fc[:-17])):
row[0] = 40
elif (row[1] == "{}".format(fc[:-17])):
row[0] = 41
elif (row[1] == "{}".format(fc[:-17])):
row[0] = 42
elif (row[1] == "{}".format(fc[:-17])):
row[0] = 43
elif (row[1] == "{}".format(fc[:-17])):
row[0] = 44
elif (row[1] == "{}".format(fc[:-17])):
row[0] = 45
elif (row[1] == "{}".format(fc[:-17])):
row[0] = 46
elif (row[1] == "{}".format(fc[:-17])):
row[0] = 47
elif (row[1] == "{}".format(fc[:-17])):
row[0] = 48
elif (row[1] == "{}".format(fc[:-17])):
row[0] = 49
elif (row[1] == "{}".format(fc[:-17])):
row[0] = 50
elif (row[1] == "{}".format(fc[:-17])):
row[0] = 51
elif (row[1] == "{}".format(fc[:-17])):
row[0] = 52
elif (row[1] == "{}".format(fc[:-17])):
row[0] = 53
elif (row[1] == "{}".format(fc[:-17])):
row[0] = 54
elif (row[1] == "{}".format(fc[:-17])):
row[0] = 55
elif (row[1] == "{}".format(fc[:-17])):
row[0] = 56
elif (row[1] == "{}".format(fc[:-17])):
row[0] = 57
elif (row[1] == "{}".format(fc[:-17])):
row[0] = 58
elif (row[1] == "{}".format(fc[:-17])):
row[0] = 59
elif (row[1] == "{}".format(fc[:-17])):
row[0] = 60
elif (row[1] == "{}".format(fc[:-17])):
row[0] = 61
elif (row[1] == "{}".format(fc[:-17])):
row[0] = 62
elif (row[1] == "{}".format(fc[:-17])):
row[0] = 63
elif (row[1] == "{}".format(fc[:-17])):
row[0] = 64
elif (row[1] == "{}".format(fc[:-17])):
row[0] = 65
elif (row[1] == "{}".format(fc[:-17])):
row[0] = 66
elif (row[1] == "{}".format(fc[:-17])):
row[0] = 67
elif (row[1] == "{}".format(fc[:-17])):
row[0] = 68
elif (row[1] == "{}".format(fc[:-17])):
row[0] = 69
elif (row[1] == "{}".format(fc[:-17])):
row[0] = 70
elif (row[1] == "{}".format(fc[:-17])):
row[0] = 71
elif (row[1] == "{}".format(fc[:-17])):
row[0] = 72
elif (row[1] == "{}".format(fc[:-17])):
row[0] = 73
elif (row[1] == "{}".format(fc[:-17])):
row[0] = 74
elif (row[1] == "{}".format(fc[:-17])):
row[0] = 75
elif (row[1] == "{}".format(fc[:-17])):
row[0] = 76
elif (row[1] == "{}".format(fc[:-17])):
row[0] = 77
else:
row[0] = None
cursor.updateRow(row)

Expected behavior:

With the String format() method I am trying to do the following:

For every feature class whenever row[1] matches the name of the feature class minus the last 17 characters, assign the specified number to row[0]. I am expecting every feature class to only have one match and as a result one number will be assigned to row[0].

Actual Behavior:

I am getting the expected behavior but only in the last feature class on the list "List_dissolve_fc".

 

I know there is something very obvious to all of this but I cannot have a clear picture of what it is.

 

How could I solve this?

Thank you,

Natalia

Reply
0 Kudos
1 Solution

Accepted Solutions
RandyBurton
MVP Regular Contributor

Seems like you want to extract a county name from a field and assign another field a county number based on the name,  you could try something like:

# dictionary of counties 
counties = { 'ALACHUA' : 1,
'BAKER' : 2,
'BAY' : 3,
'BRADFORD' : 4,
'BREVARD' : 5,
'BROWARD' : 6,
'CALHOUN' : 7,
'CHARLOTTE' : 8,
'CITRUS' : 9,
'CLAY' : 10,
'COLLIER' : 11,
'COLUMBIA' : 12,
'DESOTO' : 13,
'DIXIE' : 14,
'DUVAL' : 15
}

# dictionary keys to list
countyKey = list(counties.keys())


# example of update cursor data : fields = ["CO_NO", "COUNTY_NAME"]
cursor = [
[0, 'baker_2019pin_Dissolve'],
[0, 'calhoun_2019pin_Dissolve'],
[0, 'citrus_2019pin_Dissolve'],
[0, 'duval_2019pin_Dissolve'],
[0, 'alachua_2019pin_Dissolve'],
[0, 'clay_2019pin_Dissolve']
]

for row in cursor:
if row[1][:-17].upper() in countyKey:
row[0] = counties[row[1][:-17].upper()]
print row[0], row[1]


# prints:
2 baker_2019pin_Dissolve
7 calhoun_2019pin_Dissolve
9 citrus_2019pin_Dissolve
15 duval_2019pin_Dissolve
1 alachua_2019pin_Dissolve
10 clay_2019pin_Dissolve‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍

This uses a dictionary of county names, uses upper() to compare for a match and then uses the dictionary value for the county number.  This process is easier to code than a long if/else.

Note that you will need to have dictionary entries that will match your county names if they include spaces, underscores, etc. (St. Lucie, Miami-Dade).  It also assumes the the slicing [:-17] is correct.

Hope this helps.

View solution in original post

13 Replies
DanPatterson_Retired
MVP Esteemed Contributor

isn't your update row indented one level too far?

Reply
0 Kudos
NataliaGutierrez1
New Contributor III

Yes it was thanks!

Reply
0 Kudos
JoshuaBixby
MVP Esteemed Contributor

I am still not clear what you are trying to accomplish, but I will let you know that all of your elif statements are redundant because they are identical.  The problem with your current expressions:

row[1] == "{}".format(fc[:-17])

is that you are checking whether COUNTY_NAME matches the trimmed feature class name, but there is nothing to differentiate one county from another.  The code can't tell when to use code 72 vs 56.

NataliaGutierrez1
New Contributor III

My logic behind this is:

1. The for loop statement selects one feature class at a time.

2. It then goes through all the if /elif statements for that one feature class. 

3. Once it finds the one where the name of the field matches the name of that particular feature class it will assign the correct number.

4. The for loop then selects another feature class and goes through the same process. 

Not sure if I am thinking correctly... 

Reply
0 Kudos
JoshuaBixby
MVP Esteemed Contributor

Regarding:

2.  It then goes through all the if /elif statements for that one feature class. 

As I mentioned earlier, the current if/elif structure doesn't differentiate one feature class from another.  If the Python if statement evaluates to True, then none of the elif statements will be evaluated.  If the Python if statement evaluates to False, every elif statement will evaluate to False because it is the exact same logical check.

I have to run now, but will think about this more later....

Reply
0 Kudos
NataliaGutierrez1
New Contributor III

thank you I will edit my script to change each statement individually.

I can be totally wrong but in my mind it could work?

Every statement will be True just once.

Not sure how to explain what I am thinking

Reply
0 Kudos
JoshuaBixby
MVP Esteemed Contributor

For each row in the cursor, all of the statements will evaluate exactly the same.  Since using a debugger in an IDE is a big ask for new Python programmers, just manually walk through the code and jot down how each step will be evaluated (you don't have to do it all, just the first feature class and first couple rows of the cursor should help you understand what I am saying).

DavidPike
MVP Regular Contributor

This script makes no sense, can you be clear what you exactly want to achieve.

Reply
0 Kudos
RandyBurton
MVP Regular Contributor

Seems like you want to extract a county name from a field and assign another field a county number based on the name,  you could try something like:

# dictionary of counties 
counties = { 'ALACHUA' : 1,
'BAKER' : 2,
'BAY' : 3,
'BRADFORD' : 4,
'BREVARD' : 5,
'BROWARD' : 6,
'CALHOUN' : 7,
'CHARLOTTE' : 8,
'CITRUS' : 9,
'CLAY' : 10,
'COLLIER' : 11,
'COLUMBIA' : 12,
'DESOTO' : 13,
'DIXIE' : 14,
'DUVAL' : 15
}

# dictionary keys to list
countyKey = list(counties.keys())


# example of update cursor data : fields = ["CO_NO", "COUNTY_NAME"]
cursor = [
[0, 'baker_2019pin_Dissolve'],
[0, 'calhoun_2019pin_Dissolve'],
[0, 'citrus_2019pin_Dissolve'],
[0, 'duval_2019pin_Dissolve'],
[0, 'alachua_2019pin_Dissolve'],
[0, 'clay_2019pin_Dissolve']
]

for row in cursor:
if row[1][:-17].upper() in countyKey:
row[0] = counties[row[1][:-17].upper()]
print row[0], row[1]


# prints:
2 baker_2019pin_Dissolve
7 calhoun_2019pin_Dissolve
9 citrus_2019pin_Dissolve
15 duval_2019pin_Dissolve
1 alachua_2019pin_Dissolve
10 clay_2019pin_Dissolve‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍

This uses a dictionary of county names, uses upper() to compare for a match and then uses the dictionary value for the county number.  This process is easier to code than a long if/else.

Note that you will need to have dictionary entries that will match your county names if they include spaces, underscores, etc. (St. Lucie, Miami-Dade).  It also assumes the the slicing [:-17] is correct.

Hope this helps.

View solution in original post