如何在Python中切换值
什么是0
和1
之间切换的最有效的方法?
使用NOT的解决scheme
如果值是布尔值,最快的方法是使用not操作符:
>>> x = True >>> x = not x # toggle >>> x False >>> x = not x # toggle >>> x True >>> x = not x # toggle >>> x False
使用减法的解决scheme
如果这些值是数值,那么从总和中减去是一个简单快捷的切换值的方法:
>>> 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
使用XOR的解决scheme
如果该值在0和1之间切换,则可以使用按位异或 :
>>> x = 1 >>> x ^= 1 >>> x 0 >>> x ^= 1 >>> x 1
(这个想法是由Nick Coghlan提交的。)
使用字典的解决scheme
如果值是可散列的,你可以使用一个字典:
>>> 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'
解决scheme使用条件expression式
最慢的方法是使用条件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]
使用itertools的解决scheme
如果你有两个以上的值, itertools.cycle()函数提供了一个通用的快速方法来切换连续值:
>>> import itertools >>> toggle = itertools.cycle(['red', 'green', 'blue']).next >>> toggle() 'red' >>> toggle() 'green' >>> toggle() 'blue' >>> toggle() 'red' >>> toggle() 'green' >>> toggle() 'blue'
请注意,在Python 3中, next()
方法已更改为__next__()
,因此现在将第一行写为toggle = itertools.cycle(['red', 'green', 'blue']).__next__
我总是使用:
p^=True
如果p是布尔值,则在真和假之间切换。
这是另一种非直观的方式。 美是你可以循环多个值而不只是两个[0,1]
对于两个值(切换)
>>> x=[1,0] >>> toggle=x[toggle]
对于多个值(比如4)
>>> x=[1,2,3,0] >>> toggle=x[toggle]
我没有想到这个解决scheme几乎是最快的
>>> stmt1=""" toggle=0 for i in xrange(0,100): toggle = 1 if toggle == 0 else 0 """ >>> stmt2=""" x=[1,0] toggle=0 for i in xrange(0,100): toggle=x[toggle] """ >>> t1=timeit.Timer(stmt=stmt1) >>> t2=timeit.Timer(stmt=stmt2) >>> print "%.2f usec/pass" % (1000000 * t1.timeit(number=100000)/100000) 7.07 usec/pass >>> print "%.2f usec/pass" % (1000000 * t2.timeit(number=100000)/100000) 6.19 usec/pass stmt3=""" toggle = False for i in xrange(0,100): toggle = (not toggle) & 1 """ >>> t3=timeit.Timer(stmt=stmt3) >>> print "%.2f usec/pass" % (1000000 * t3.timeit(number=100000)/100000) 9.84 usec/pass >>> stmt4=""" x=0 for i in xrange(0,100): x=x-1 """ >>> t4=timeit.Timer(stmt=stmt4) >>> print "%.2f usec/pass" % (1000000 * t4.timeit(number=100000)/100000) 6.32 usec/pass
not
运算符否定variables(如果它不是一个variables,则将其转换为布尔值)。 你可以用1
和0
交替使用True
和False
,所以只是否定它:
toggle = not toggle
但是,如果您使用两个任意值,请在以下情况下使用内联:
toggle = 'a' if toggle == 'b' else 'b'
在1到0之间,就这样做
1-x
x可以取1或0
令人惊讶的是,没有人提到好的旧分区模2:
In : x = (x + 1) % 2 ; x Out: 1 In : x = (x + 1) % 2 ; x Out: 0 In : x = (x + 1) % 2 ; x Out: 1 In : x = (x + 1) % 2 ; x Out: 0
注意这相当于x = x - 1
,但是模数技术的优点是组的大小或者区间的长度可以大于2个元素,因此给出了类似于循环法的交错scheme循环。
现在只需要2,切换可以有点短(使用按位运算符):
x = x ^ 1
一种切换方法是使用多个赋值
>>> a = 5 >>> b = 3 >>> t = a, b = b, a >>> t[0] 3 >>> t = a, b = b, a >>> t[0] 5
使用itertools:
In [12]: foo = itertools.cycle([1, 2, 3]) In [13]: next(foo) Out[13]: 1 In [14]: next(foo) Out[14]: 2 In [15]: next(foo) Out[15]: 3 In [16]: next(foo) Out[16]: 1 In [17]: next(foo) Out[17]: 2
使用exception处理程序
>>> def toogle(x): ... try: ... return x/xx/x ... except ZeroDivisionError: ... return 1 ... >>> x=0 >>> x=toogle(x) >>> x 1 >>> x=toogle(x) >>> x 0 >>> x=toogle(x) >>> x 1 >>> x=toogle(x) >>> x 0
好的,我是最差的:
import math import sys d={1:0,0:1} l=[1,0] def exception_approach(x): try: return x/xx/x except ZeroDivisionError: return 1 def cosinus_approach(x): return abs( int( math.cos( x * 0.5 * math.pi ) ) ) def module_approach(x): return (x + 1) % 2 def subs_approach(x): return x - 1 def if_approacj(x): return 0 if x == 1 else 1 def list_approacj(x): global l return l[x] def dict_approacj(x): global d return d[x] def xor_approach(x): return x^1 def not_approach(x): b=bool(x) p=not b return int(p) funcs=[ exception_approach, cosinus_approach, dict_approacj, module_approach, subs_approach, if_approacj, list_approacj, xor_approach, not_approach ] f=funcs[int(sys.argv[1])] print "\n\n\n", f.func_name x=0 for _ in range(0,100000000): x=f(x)
三angular函数法 ,只是因为sin
和cos
函数很酷。
>>> import math >>> def generator01(): ... n=0 ... while True: ... yield abs( int( math.cos( n * 0.5 * math.pi ) ) ) ... n+=1 ... >>> g=generator01() >>> g.next() 1 >>> g.next() 0 >>> g.next() 1 >>> g.next() 0
我使用abs函数,在循环中非常有用
x = 1 for y in range(0, 3): x = abs(x - 1)
x将是0。
快开始…
def toggle(x = []): x.append('#') return len(x) % 2
在1和0之间切换的最简单的方法是从1中减去。
def toggle(value): return 1 - value