1

I saw a peculiar behavior in python when using ternary operator in string concatenation -

>>> foo = "foo"
>>> foo.upper()
'FOO'
>>> bar = 2
>>> "" if bar is 0 else str(bar)
'2'
>>> foo.upper() + "_" + "" if bar is 0 else str(bar)
'2'

With the above code I was expecting it should output as FOO_2 but only showing 2. Though I can achieve the output with the below code. Can anyone explain why it is not working with + ?

>>> "{}_{}".format(foo.upper(), "" if bar is 0 else str(bar))
'FOO_2'
alecxe
  • 462,703
  • 120
  • 1,088
  • 1,195
Anirban Nag 'tintinmj'
  • 5,572
  • 6
  • 39
  • 59
  • https://docs.python.org/3/reference/expressions.html#operator-precedence – user2357112 Jan 04 '18 at 04:10
  • Aside: it's not relevant to your issue, but don't use `is` where you mean `==` -- see [here](https://stackoverflow.com/questions/306313/is-operator-behaves-unexpectedly-with-integers) or [here](https://stackoverflow.com/questions/132988/is-there-a-difference-between-and-is-in-python). – DSM Jan 04 '18 at 04:27

1 Answers1

4

The operator precedence plays a crucial role here. The expression is evaluated as:

(foo.upper() + "_" + "") if bar is 0 else str(bar)

This is because conditional expressions precede addition and subtraction.

Use parenthesis to enforce your desired evaluation order:

foo.upper() + "_" + ("" if bar is 0 else str(bar))

Or, what is probably even better is to decrease complexity by extracting a variable to avoid any possible confusion:

postfix = "" if bar is 0 else str(bar)
print(foo.upper() + "_" + postfix)
alecxe
  • 462,703
  • 120
  • 1,088
  • 1,195