What is the most efficient way to toggle between 0
and 1
?
The not
operator negates your variable (converting it into a boolean if it isn't already one). You can probably use 1
and 0
interchangeably with True
and False
, so just negate it:
toggle = not toggle
But if you are using two arbitrary values, use an inline if
:
toggle = 'a' if toggle == 'b' else 'b'
Variables a and b can be ANY two values, like 0 and 1, or 117 and 711, or "heads" and "tails". No math is used, just a quick swap of the values each time a toggle is desired.
a = True
b = False
a,b = b,a # a is now False
a,b = b,a # a is now True
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
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
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.)
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'
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]
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__
Let's do some frame hacking. Toggle a variable by name. Note: This may not work with every Python runtime.
Say you have a variable "x"
>>> import inspect
>>> def toggle(var_name):
>>> frame = inspect.currentframe().f_back
>>> vars = frame.f_locals
>>> vars[var_name] = 0 if vars[var_name] == 1 else 1
>>> x = 0
>>> toggle('x')
>>> x
1
>>> toggle('x')
>>> x
0
Switching between -1 and +1 can be obtained by inline multiplication; used for calculation of pi the 'Leibniz' way (or similar):
sign = 1
result = 0
for i in range(100000):
result += 1 / (2*i + 1) * sign
sign *= -1
print("pi (estimate): ", result*4)
The easiest way to toggle between 1 and 0 is to subtract from 1.
def toggle(value):
return 1 - value