如果您需要在一个周期内将变量值在0和1之间切换,您更喜欢性能(内存消耗,速度)/ 可读性:
x=get(x)
for i in range (start, end):
if x==0:
x=1
else:
x=0
或
x=get(x)
for i in range (start, end):
x = ((x + 1) % 2)
python编译器如何解释它?
答案 0 :(得分:4)
除了您使用的if
语句和表达式之外,还有很多选项。
使用减法:
x = 1 - x
使用^
(XOR):
for i in range (start, end):
x ^= 1
这在0和1之间切换:
>>> x = 1
>>> x ^ 1
0
>>> x ^= 1
>>> x ^ 1
1
您可以使用itertools.cycle()
:
from itertools import cycle
x_values = cycle((0, 1))
for i in range (start, end):
x = next(x_values)
cycle()
对于在多个值之间进行交换特别有用,尤其是当它们之间没有简单的数学或逻辑关系时:
>>> from itertools import cycle
>>> x_values = cycle((1, 'spam', 3.14))
>>> next(x_values)
1
>>> next(x_values)
'spam'
>>> next(x_values)
3.14
>>> next(x_values)
1
但要找出最适合你的方法,选择一个指标并坚持下去。为了提高性能,请使用timeit
module进行比较试验。
使用x - 1
远远快于cycle()
或您的表达式,例如:
>>> from timeit import timeit
>>> timeit('x = 1 - x', 'x = 0')
0.044335126876831055
>>> timeit('x ^= 1', 'x = 0')
0.05133986473083496
>>> timeit('x = ((x + 1) % 2)', 'x = 0')
0.11392998695373535
>>> timeit('x = next(x_values)', 'from itertools import cycle; x_values = cycle((0, 1))')
0.1254570484161377
Python编译器主要解释代码非常简单。例如,您的if
版本不会被优化。使用dis.dis()
function查看编译器输出的反汇编:
>>> import dis
>>> def foo():
... if x==0:
... x=1
... else:
... x=0
...
>>> dis.dis(foo)
2 0 LOAD_FAST 0 (x)
3 LOAD_CONST 1 (0)
6 COMPARE_OP 2 (==)
9 POP_JUMP_IF_FALSE 21
3 12 LOAD_CONST 2 (1)
15 STORE_FAST 0 (x)
18 JUMP_FORWARD 6 (to 27)
5 >> 21 LOAD_CONST 1 (0)
24 STORE_FAST 0 (x)
>> 27 LOAD_CONST 0 (None)
30 RETURN_VALUE
正如您所见,完整的分支结构仍然存在。使用表达式会导致字节码非常不同:
>>> def bar():
... x = ((x + 1) % 2)
...
>>> dis.dis(bar)
2 0 LOAD_FAST 0 (x)
3 LOAD_CONST 1 (1)
6 BINARY_ADD
7 LOAD_CONST 2 (2)
10 BINARY_MODULO
11 STORE_FAST 0 (x)
14 LOAD_CONST 0 (None)
17 RETURN_VALUE
答案 1 :(得分:0)
您可以使用xor运算符^
在0
和1
之间切换:
x ^= 1