What is the most efficient way to toggle between 0
and 1
?
Advertisement
Answer
Solution using NOT
If the values are boolean, the fastest approach is to use the not operator:
>>> x = True >>> x = not x # toggle >>> x False >>> x = not x # toggle >>> x True >>> x = not x # toggle >>> x False
Solution using subtraction
If the values are numerical, then subtraction from the total is a simple and fast way to toggle values:
>>> A = 5 >>> B = 3 >>> total = A + B >>> x = A >>> x = total - x # toggle >>> x 3 >>> x = total - x # toggle >>> x 5 >>> x = total - x # toggle >>> x 3
Solution using XOR
If the value toggles between 0 and 1, you can use a bitwise exclusive-or:
>>> x = 1 >>> x ^= 1 >>> x 0 >>> x ^= 1 >>> x 1
The technique generalizes to any pair of integers. The xor-by-one step is replaced with a xor-by-precomputed-constant:
>>> A = 205 >>> B = -117 >>> t = A ^ B # precomputed toggle constant >>> x = A >>> x ^= t # toggle >>> x -117 >>> x ^= t # toggle >>> x 205 >>> x ^= t # toggle >>> x -117
(This idea was submitted by Nick Coghlan and later generalized by @zxxc.)
Solution using a dictionary
If the values are hashable, you can use a dictionary:
>>> A = 'xyz' >>> B = 'pdq' >>> d = {A:B, B:A} >>> x = A >>> x = d[x] # toggle >>> x 'pdq' >>> x = d[x] # toggle >>> x 'xyz' >>> x = d[x] # toggle >>> x 'pdq'
Solution using a conditional expression
The slowest way is to use a conditional expression:
>>> A = [1,2,3] >>> B = [4,5,6] >>> x = A >>> x = B if x == A else A >>> x [4, 5, 6] >>> x = B if x == A else A >>> x [1, 2, 3] >>> x = B if x == A else A >>> x [4, 5, 6]
Solution using itertools
If you have more than two values, the itertools.cycle() function provides a generic fast way to toggle between successive values:
>>> import itertools >>> toggle = itertools.cycle(['red', 'green', 'blue']).next >>> toggle() 'red' >>> toggle() 'green' >>> toggle() 'blue' >>> toggle() 'red' >>> toggle() 'green' >>> toggle() 'blue'
Note that in Python 3 the next()
method was changed to __next__()
, so the first line would be now written as toggle = itertools.cycle(['red', 'green', 'blue']).__next__