Tertiary Operation

Steven D'Aprano steve at REMOVE.THIS.cybersource.com.au
Tue Oct 17 16:07:16 CEST 2006

On Tue, 17 Oct 2006 06:30:32 -0700, abcd wrote:

> x = None
> result = (x is None and "" or str(x))

Boolean operators "and" and "or" stop as soon as a result is known. So:

X and Y evaluates as X if X is false; otherwise it evaluates as Y.
X or Y evaluates as X if X is true; otherwise it evaluates as Y.

(x is None) evaluates as true, so (x is None and "") evaluates as "".
("") evaluates as false, so ("" or str(None)) evaluates as str(None).

The important factor you missed is, I think, that the empty string is
false in a boolean context.

>>> if '':
...     print "empty string evaluates as true"
... else:
...     print "empty string evaluates as false"
empty string evaluates as false

> y = 5
> result = (y is 5 and "it's five" or "it's not five")

(y is 5) evaluates as true, so (y is 5 and "it's five") evaluates as "it's
"it's five" evaluates as true, so ("it's five" or ""it's not five")
evaluates as "it's five".

Your basic logic is okay, but you shouldn't test equality with "is".

== tests for equality;
is tests for object identity.

In the case of None, it is a singleton; every reference to None refers to
the same object. But integers like 5 aren't guaranteed to be singletons.
In your case, you were lucky that, by a fluke of implementation, "y is 5"
was true. But watch:

>>> 1+4 is 5
>>> 10001 + 10004 == 10005
>>> 10001 + 10004 is 10005

Always use == to test for equality, and (is) only to test for actual
object identity ("is this object the same as this one, not just two
objects with the same value?").


More information about the Python-list mailing list