Wednesday, 2nd March 2011
Boolean indices
In Python, not only is 0 False and 1 True, but True is 1 and False is 0. This means you can do weird things like:
>>> a = 1 >>> (a==1) + (a>0) + (a==2) 2
I'm not sure why you'd want to do this unless you wanted to count how many conditions had been met. More usefully, you can use a boolean test as an index for an array or tuple. For example, rather than write:
if a % 2 == 0:
print "a is even"
else:
print "a is odd"
You can write:
print ("a is odd", "a is even")[a % 2 == 0]
Admittedly, this is probably less readable.
Examples
An example of when I've found this trick useful is when I wanted to create a play/pause button. In response to a keystroke, I wanted flip the value of a boolean variable call 'paused': if it was currently True then it should becomes False, if it were False then it should become True. This can be achieve like so:
paused = (True, False)[paused]
Another situation in which using a boolean test as a index might be useful is when you don't have the luxury of writing multiple lines of code, e.g. within a lambda function or list comprehension. For example:
>>> my_list = [1, 7, 11, 8, 13, 2]
>>> [("odd","even")[i % 2 == 0] for i in my_list]
["odd","odd","odd","even","odd","even"]
A more useful example would be to threshold a list of data:
thresholded_data = [(0,1)[i > threshold] for i my_list]
But in that situation, it's easier to just coerce the test into an integer:
thresholded_data = [int(i > threshold) for i my_list]
Comments
Great tricks. Thanks!
To flip a boolean, why not simply use the following?
paused = !paused
`print 'a is even' if a%2==0 else 'a is odd'` is much more readable than `print ("a is odd", "a is even")[a % 2 == 0]` and `paused = not paused` is a much more readable than `paused = (True, False)[paused]`.
Boolean indices is indeed a clever trick, but Python gives you much more readable ways of doing things like this.
Post new comment