如何在Python中切换值

什么是01之间切换的最有效的方法?

使用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

如果该值在01之间切换,则可以使用按位异或 :

 >>> 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,则将其转换为布尔值)。 你可以用10交替使用TrueFalse ,所以只是否定它:

 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函数法 ,只是因为sincos函数很酷。

在这里输入图像说明

 >>> 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