Conditional Calculate Field in Python

4044
8
06-16-2015 01:31 PM
CoyPotts1
Occasional Contributor III

I have a script that works, but I replicate it in order to conditionally update 5 different fields.  I would like to bolster the script to conditionally calculate all 5 fields into one if I can. 

# Calculate Region

# Set local variables
inTable = nodeFeatures
inField = "Region1"
expression = "Reclass (!NodeID1!, !Region1!)"
codeBlock = """def Reclass (NodeID1, Region1):
    if NodeID1 != None:
        return region    #variable is declared earlier in the script
    else:
        return None"""

# Execute CalculateField
arcpy.CalculateField_management(inTable, inField, expression, "PYTHON_9.3", codeBlock)

The script above works just fine, but as I mentioned, I end up duplicating it to calculate 4 other fields.  In this example we'll call all 5 fields Region1, Region2, etc...  They would all have an accompanying NodeID1, NodeID2, etc...

Is it possible to expand upon this script in order to reduce the 5 separate scripts to calculate them all in one, or is it just the way it has to be in order to calculate a value of completely separate fields?


Thanks in advance!

0 Kudos
8 Replies
WesMiller
Regular Contributor III
CoyPotts1
Occasional Contributor III

Wow, that's some pretty cool stuff!  Thanks for sharing. 

0 Kudos
DarrenWiens2
MVP Honored Contributor

You can place everything in a loop, counting from 1 - 5. Then, it's a matter of substituting the value into your expressions. This is untested, and I almost promise I got something wrong, but it should be a start:

# Calculate Region  

for i in range(1,6):  
    # Set local variables  
    inTable = nodeFeatures  
    inField = "Region" + i  
    expression = "Reclass (!NodeID" + i +"!, !Region" + i + "!)"  
    codeBlock = """def Reclass (NodeID" + i + ", Region" + i + "): 
        if NodeID" + i + "!= None: 
            return region    #variable is declared earlier in the script 
        else: 
            return None"""  
  
    # Execute CalculateField  
    arcpy.CalculateField_management(inTable, inField, expression, "PYTHON_9.3", codeBlock) 
CoyPotts1
Occasional Contributor III

This looks like it'll do just what I need.  I'll give it a try a little later and respond with my results.  Thanks for responding. 

0 Kudos
CoyPotts1
Occasional Contributor III

Actually, I made an oversight when I pasted my code.  I omitted some of the verbiage to not include customer names and whatnot, so instead of each NodeID field literally having a number after it, each number actually represents a customer name. 


But I will still use your sample code as reference for a FOR statement!  .

Can you think of a way to do it without the FOR iteration?

0 Kudos
DarrenWiens2
MVP Honored Contributor

Do you mean you want to loop through names, rather than numbers? If so, you can iterate through a list:

>>> list = ['Bob','Dave','Henry']
... for name in list:
...    print name
Bob
Dave
Henry

...or a dictionary:

>>> dict = {1:'a', 2:'b', 3:'c'}
... for item in dict:
...     print item
...     print dict[item]
...     
1
a
2
b
3
c

...or a tuple:

>>> tuple = (1, 2, 3)
... for item in tuple:
...     print item
...     
1
2
3

You can loop through unexpected things, too:

>>> string = "Hello"
... for letter in string:
...     print letter
...     
H
e
l
l
o
CoyPotts1
Occasional Contributor III

This may be getting me in the right direction.

The feature class that I am using has duplicate fields for each customer, so say each customer has the same 20 fields, and the only difference between them is their customer identification.

I want to loop through and say something like the following:

if Customer1NodeID != None:
     return regionvariable
if Customer2NodeID != None:
     return regionvariable
if Customer3NodeID != None:
     return regionvariable
else:
     return None

I'm just not sure how to nest multiple fields to be updated into one loop.  Essentially I have 5 customers that I want to add data to their respective fields, but only if their NodeID field has data in it, otherwise leave it blank.

0 Kudos
DanPatterson_Retired
MVP Emeritus

as an example...there are better data structures ( eg dict)

>>>
>>> in_group = ['a','b','c','d','e']
>>> has_stuff = ['a','d','e']
>>> for i in in_group:
...  if i in has_stuff:
...  print("{} from the in_group has stuff".format(i))
...  else:
...  print("{}'s got nothing...".format(i))
... 
a from the in_group has stuff
b's got nothing...
c's got nothing...
d from the in_group has stuff
e from the in_group has stuff
>>>
0 Kudos