You are here: Home > Dive Into Python > The Power Of Introspection > The peculiar nature of and and or | << >> | ||||
Dive Into PythonPython for experienced programmers |
In Python, and and or perform boolean logic as you would expect, but they do not return boolean values; they return one of the actual values they are comparing.
>>> 'a' and 'b' 'b' >>> '' and 'b' '' >>> 'a' and 'b' and 'c' 'c'
When using and, values are evaluated in a boolean context from left to right. 0, '', [], (), {}, and None are false in a boolean context; everything else is true.[3] If all values are true in a boolean context, and returns the last value. In this case, and evaluates 'a', which is true, then 'b', which is true, and returns 'b'. | |
If any value is false in a boolean context, and returns the first false value. In this case, '' is the first false value. | |
All values are true, so and returns the last value, 'c'. |
>>> 'a' or 'b' 'a' >>> '' or 'b' 'b' >>> '' or [] or {} {} >>> def sidefx(): ... print "in sidefx()" ... return 1 >>> 'a' or sidefx() 'a'
If you’re a C hacker, you are certainly familiar with the bool ? a : b expression, which evaluates to a if bool is true, and b otherwise. Because of the way and and or work in Python, you can accomplish the same thing.
>>> a = "first" >>> b = "second" >>> 1 and a or b 'first' >>> 0 and a or b 'second'
However, since this Python expression is simply boolean logic, and not a special construct of the language, there is one very, very, very important difference between this and-or trick in Python and the bool ? a : b syntax in C. If the value of a is false, the expression will not work as you would expect it to. (Can you tell I was bitten by this? More than once?)
The and-or trick, bool and a or b, will not work like the C expression bool ? a : b when a is false in a boolean context. |
The real trick behind the and-or trick, then, is to make sure that the value of a is never false. One common way of doing this is to turn a into [a] and b into [b], then taking the first element of the returned list, which will be either a or b.
>>> a = "" >>> b = "second" >>> (1 and [a] or [b])[0] ''
By now, this trick may seem like more trouble than it’s worth. You could, after all, accomplish the same thing with an if statement, so why go through all this fuss? Well, in many cases, you are choosing between two constant values, so you can use the simpler syntax and not worry, because you know that the a value will always be true. And even if you have to use the more complicated safe form, there are good reasons to do so; there are some cases in Python where if statements are not allowed, like lambda functions.
[3] Well, almost everything. By default, instances of classes are true in a boolean context, but you can define special methods in your class to make an instance evaluate to false. You’ll learn all about classes and special methods in chapter 3.
<< Filtering lists |
| 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | |
Using lambda functions >> |