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!
See Richard Fairhurst's blog Turbo Charging Data Manipulation with Python Cursors and Dictionaries
Wow, that's some pretty cool stuff! Thanks for sharing.
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)
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.
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?
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
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.
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 >>>