2013-10-09 95 views
2

與IPython中玩的時候,我很驚訝地發現,給定一個列表支持一些方法x()(即,比如說,打印出"Hi!")每個對象的f,表達:在Python中,列表理解與列表和元組有什麼區別?

(y.x() for y in f) 

不是語義上等同於

[y.x() for y in f] 

第一個(與元組作爲輸出)中,除非我遍歷它未被評估的發電機表達的結果,而所述一個與所述列表實際上導致產生立即發生:

In [30]: (y.x() for y in f) 
Out[30]: <generator object <genexpr> at 0x2d78d70> 

In [31]: [y.x() for y in f] 
Hi! 
Hi! 
Hi! 
Hi! 

這似乎相當反直覺的。

問題:爲什麼第一個表達式不會生成從生成器獲得的值的元組,這正是構建列表的方式?


更新:正如我盯着這個多了,我意識到,也許發生的事情在第一種情況是,Python是剛剛建立包含有發電機的元組,而不是評估發生器,因爲它是在第二案件。

因此,是不是可以直接得到一個元組作爲生成列表理解的結果? (我明白我可以做tuple([y.x() for y in f]))。我沒有用例,這純粹是爲了我的理解。

+0

爲什麼是什麼?你已經發現了它的含義,即使它不是你最初的預期。你在問爲什麼生成器表達式存在?或者你問爲什麼這個語法不會生成元組(類似於列表理解)?或者是其他東西? – delnan

+0

你在問爲什麼它是違反直覺的,或者爲什麼存在基因? –

+0

如果它是違反直覺的,那意味着你期待其他一些行爲。你在期待什麼? – recursive

回答

3

有些人將元組視爲只讀列表,並且在某些情況下起作用。但這不是元組的語義意圖。列表旨在用於同構元素的可變長度結構(具有共享類型的元素)。元組適用於固定長度結構,其中每個索引位置都包含某種類型的元素。

enumerate(lst)就是這樣的一個例子。它返回一個可變長度的元組列表。每個元組只有兩個元素,第一個元素始終是一個整數,第二個元素是從lst

有了這樣的理解,元組生成器有點無意義。這可能是爲什麼。

編輯:

至於直接生成一個元組,你可以做一點點比你更好的例子。這也適用:

tuple(y.x() for y in f) 

即通過一個發電機到tuple()方法,它構造元組,但不創建中間list

要清楚,(y.x() for y in f)中沒有涉及tuple,但在t = 1, 2, 3中有一個元組。這不是構成元組的元素。這是逗號。

0

問題:爲什麼第一個表達式不會生成從生成器獲得的 值的元組與列表的構建方式?

這不是設計的目的。
請參閱PEP-289
Tutorial始終是開始尋找答案的好地方。
Generator Expressions
Expression lists - 介紹定義使用逗號的元組

因此,它是真的,它是不可能直接得到一個元組作爲生成列表理解的 結果?

不 - 不像列表理解,它是一個生成器。它旨在爲每次迭代產生單獨的元素