2013-09-30 50 views
-3

你喜歡什麼就性能(內存消耗,速度)/ 可讀性,如果你需要在一個週期0和1之間切換變量值:if語句與表達

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

看一看[數碼防抖](http://docs.python.org/2.7/library/dis.html#module-dis)模塊。使用它,看看字節碼,如果這是你不明白的東西,就回到這裏。 –

+3

'x = 1 - x'爲簡潔起見。 – dornhege

+0

..併爲更好的方法來切換值,請參閱http://stackoverflow.com/questions/10986970/python-how-to-toggle-between-two-values –

回答

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

+1提及週期。 – Alfe

+0

謝謝,那正是我需要的! –

0

您可以使用XOR運算^切換01之間:

x ^= 1