2017-07-13 25 views
2

當我運行這個迭代:有什麼意義 「國際熱核實驗堆(拉姆達:對象()>對象(),對象())」

iter(lambda : object() > object(), object()) 

迭代器連續輸出TrueFalse

但是,它是什麼意思,它是如何執行的?

+1

這似乎是一種創造無限迭代器的真正愚蠢的方式,即「真」與「假」之間的替代方案。它也只能在Python 2上工作,即使在那裏,它依賴於實現細節。 –

+1

@ juanpa.arrivillaga我想知道它爲什麼會發生。謹慎寫一個答案? –

+0

你不明白什麼?你看過文檔嗎?它使用所有內置函數... [這裏](https://docs.python.org/2/library/stdtypes.html#comparisons)是最後的提示,不是很明顯。事實上,所有這些在Python 3中都發生了變化,因爲行爲並不理想。類型之間的比較是不支持的比較應該報錯了,別有一番任意默認排序是一個實現細節... –

回答

5

正如評論已經指出,這是一個實現細節,它只是「碰巧」給的TrueFalse交替序列(然而,一個無法預測,如果第一個是TrueFalse)。

讓我們先從約2.7 CPython的一些事實:

  • 如果在python-2.x的對象沒有實現__eq__並進行比較,其比較的內存不會忽略同一類型的另一個對象。
  • 有些記憶不會忽略重新用在LIFO(後進先出)的方式

讓我們來看看你的那個迭代器,這個時候有未lambda函數和print S代表內存地址:

def cmp_objects(): 
    a = object() 
    b = object() 
    print id(a) 
    print id(b) 
    print a > b 

x = iter(cmp_objects, object()) 
next(x), next(x), next(x), next(x), next(x) 

這給:

69637872 
69638064 
False 
69638064 
69637872 
True 
69637872 
69638064 
False 
69638064 
69637872 
True 
69637872 
69638064 
False 

所以a變量開始與的存儲器地址和b69638064。由於b的內存地址較大,因此返回False。在下一次調用中,內存地址被交換(記住LIFO),依此類推。

由於定點(第二個參數iter)的存儲器地址是從TrueFalse循環從未停止存儲器ADRESS不同並給出交替TrueFalse


然而,一個更好的方式來獲得這樣的順序將是:

>>> import itertools 
>>> it = itertools.cycle((True, False)) 

這也有一個可預測的第一產生了價值。它還如果object s的創建不破next調用之間:

>>> x = iter(lambda : object() > object(), object()) 
>>> next(x) 
True 
>>> object() 
<object at 0x4269610> 
>>> next(x) 
True 

這個例子可能會給出不同的結果,這樣的結果是完全隨機的!