I am new to python. I am using a model to automate a data update process. Part of the model is to calculate a new field by concatenating 3 other fields and left trimming to remove white space as needed. Below is the VB expression. When I use python to automatically run this model it fails at the expression to calculate the field. Below is the VB expression. I cannot find an example of how this would look as a python expression. Can anyone help?
FullStreet =
LTrim( [LOCN] &" " & LTrim( [LOCD] & " " & [LOCS]))
Any help would be greatly appreciated.
Sincerely,
Nita L Hester
Thanks James! You're the best. I didn't have time to write this up and this works great.
I think we are getting close. I tryed your instructions but get a syntax error on line 4. I cannot find anything wrong though.
Let me try to better explain what I am trying to do.
LOCN = House Number
LOCD = Street direction (i.e. N, S, E, W)
LOCS = Street Name (i.e Somewhere Blvd)
Some records have only the LOCS.
Some records have the LOCN and LOCS
Some records have LOCN, LOCD, and LOCS
I need to get the end result of:
Somewhere Blvd, or
S Somewhere Blvd, or
1234 Somewhere Blvd, or
1234 S Somewhere Blvd.
With the VB expression it concatenates the LOCD and LOCS, then trims any space before the result so that if there is no LOCD it will only have the street name and remove the hard coded space. LTrim( [LOCD] & " " & [LOCS]). Then the next part is to join that result to the first part. LTrim( [LOCN] &" " & LTrim( [LOCD] & " " & [LOCS]))
The end result is that no matter what fields have values, there are spaces when needed and no extra spaces when not.
Does this explain it better? if I just do !LOCD! + !LOCS! that gives me either just the LOCS or adds the LOCD and LOCS with no space between. That is as far as I get.
I really appreciate everyones help on this!!!!!!!
You can do it in one line with a list comprehension. The `if` statement in the list comprehension will handle empty strings.
Field calculator expression:
' '.join([s.lstrip() for s in (!LOCN,!LOCD!,!LOCS!) if s])
Basic python (assumes LOC* variables already defined)
' '.join([s.lstrip() for s in (LOCN,LOCD,LOCS) if s])
Luke Pinner, this is definitely the most idiomatic and elegant in my mind. I would give 2 helpfuls if I could.
I know the OP used LTRIM, which is probably why you used lstrip(), but I wonder if using strip() would be better for the OP. One very minor comment, the list comprehension can be swapped for a generator expression, which then allows the expression brackets to be dropped:
' '.join(s.lstrip() for s in (LOCN,LOCD,LOCS) if s)
I am using the Calculate Field tool in my model. how would I write this?
I do not know what to put in place of ' '. in your expression.
Total pro.
Thanks for your help. I think we are almost there....
Here is the modified codeblock based on you instructions:
def processInput(input1, input2, input3):
if len(input1) == 0 and len(input2) == 0:
return input3
elif len(input1)>0 and input2 == "" :
return input1 + " " + input3
elif input1 == "" and len(input2)>0 :
return input2 + " " + input3
else:
return input1 + " " + input2 + " " + input3
processInput( !LOCN!.strip(), !LOCD!.strip(), !LOCS!.strip())
Now the only problem is the first statement. If there is no value in input 1 & 2 it does not return input 3. It is blank. I tried to add the .strip to make sure there was no spaces in the field if no other value. I also tried changing from "" to len(input1) == 0, but it still does not put a value in for just the LOCS (street name) if that is the only field that has a value.
Any suggestions?
Nita
You may have mentioned this already, but the examples will work with TEXT field types (eg, it's possible LOCN or you address Number column is actually a number type column?). Anyway...
See if this adaptation works better. It's just looking for empty strings (ie, "not input1") or actual strings (ie, "input1"). Also, in my sample data I thought I was looking at an empty value but it actually had a space in it --- so it was treated as an actual value and did not evaluate as expected. This is why I included the .strip() into the input variables).
def processInput(input1, input2, input3): if (not input1.strip()) and (not input2.strip()): return input3.lstrip() elif (input1.strip()) and (not input2.strip()): return input1 + " " + input3 elif (not input1.strip()) and (input2.strip()): return input2 + " " + input3 else: return input1 + " " + input2 + " " + input3
(I wish I could write this more elegantly like some of the other contributors! Need to work on that)
This works the same as the other. I really appreciate your help. It still does not populate the FullStreet field when there is only a value in input3. Everything else works though. processInput( !LOCN!.strip(), !LOCD!.strip(), !LOCS!.strip()) (this is the Expression) Do I need to change this since it is in the code block?
(By the way this is Nita from the City of North Port. We used to work together)
Thanks,
Nita
I thought so! Hope all is well! (City of North Port was my first consulting gig many moons ago).
I'll have to dig a bit to see what else might be the problem. It's always a challenge to work thru nulls, empty strings and those that appear to be empty but are padded.