Multiple replacements with Field Calculations using Python

9722
15
Jump to solution
08-26-2015 06:18 AM
LeonardSpringer
New Contributor

I am able to make replacements one at a time following these instructions:

Simple calculations

Simple string examples

Strings are supported by a series of Python string functions, including capitalize, rstrip, and replace.

Replace any occurrences of "california" with "California" found in the field STATE_NAME.

!STATE_NAME!.replace("california", "California")

How do I make several replacements at a time? For example, how do I change “california” and “cal” and “CA” and “Cal” to “California” and “florida” and “fla” and “FL” and “Fla” to “Florida” without having to create a new field for STATE NAME for each individual replacement?

Thanks, Len Springer

0 Kudos
15 Replies
DarrenWiens2
MVP Honored Contributor

Welllll, you're welcome to explore the regex library​, but I've only done so cursorily. Easier, you could make a dictionary with the full name paired with the shortened name, then compare the first two characters against that. Note that you'll have issues in cases like Arkansas and Arizona:

dict = {'California':'ca', 'Florida':'fl'} # and so on
for k,v in dict.iteritems(): # loop through key/value pairs  
        for abbrev in v: # loop through the abbreviation list  
            if search[:2] == abbrev: # compare first two characters
                return k # return the state  
    return search # else return original 

ChrisDonohue__GISP
MVP Alum

I'll have to have a word with Congress about our state names.  Maybe if we renamed them to be more distinctly unique, think of all the money saved and confusion avoided.... 

Chris Donohue, GISP

0 Kudos
JoshuaBixby
MVP Esteemed Contributor

Regular expressions are extremely worthwhile, especially since they are a language in and of themselves so your knowledge can be transferred beyond Python.

IanMurray
Frequent Contributor

Definitely a more pythonic solution and in the case of having more states would be significantly improved over my version.

I should really use dictionaries more often, but since I only use python with arcgis I haven't used them alot(exception of storing data from cursors with them).

0 Kudos
DanPatterson_Retired
MVP Emeritus

no fancy function but the logic is the same as dictionaries...what is easiest to convert your data to???  If your table has missing keys...I have opted to leave out the flawed entry.  You can alter this behaviour.

>>> data = ['CA', 'Fla', 'Cal', 'FL', 'Ontario']
>>> innies = [[["california", "cal","CA","Cal"],"California"],[["florida","fla","FL","Fla"],"Florida"]]
>>> outies=[]
>>> for j in data:
...  for i in innies:
...  if j in i[0]:
...    outies.append(i[1])
...   
>>> outies
['California', 'Florida', 'California', 'Florida']
>>>
JoshuaBixby
MVP Esteemed Contributor

There are numerous ways to address this issue, some of which have already been raised here.  A Google search for "python replace multiple strings" will yield even more ideas, some of them with fairly in-depth discussions.

If you want to stick with using the Field Calculator, then you are going to have to use code blocks.  Another option would be to use ArcPy cursors, the Data Access ones are the newest and best.

An approach I have used in the past that is simple, and seems to perform well enough with my data sets, is a variation of a suggestion from a Stack Exchange/Overflow post:  How can I do multiple substitutions using regex in python?

import re
repls = {
    'california': 'California',
    'cal': 'California',
    'ca': 'California',
    'florida':'Florida',
    'fl':'Florida'
}
def multiple_replace(text):
    regex = re.compile("(%s\\b)" % "\\b|".join(map(re.escape, repls.keys())),re.I)
    return regex.sub(lambda mo: repls[mo.string[mo.start():mo.end()].lower()], text)

The above code goes in the code block, and the field box would be multiple_replace(!State!).

A couple of notes.

  • You will need some kind of mapping between what you want to replace and what you are replacing it with.  In this example, a dictionary is being used but other Python data structures could be used as well.
  • The posted code works on upper or lower case, but the dictionary keys need to be lowercase or you will get a Key Error potentially.