-3

如果您需要在循环中在 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编译器如何解释它?

4

2 回答 2

4

if除了您使用的语句和表达式之外,还有许多选项。

  • 使用减法:

    x = 1 - x
    
  • 使用^(异或):

    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模块进行比较试验。

usingx - 1cycle()or 你的表达要快得多,例如:

>>> 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()函数查看编译器输出的反汇编:

>>> 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        
于 2013-09-30T09:10:44.473 回答
0

您可以使用 xor 运算符在和^之间切换:01

x ^= 1
于 2013-09-30T09:09:29.733 回答