2012-10-16 50 views
17

我熟悉for循環在塊代碼上下文中。例如:Python`for`語法:塊代碼與單行生成器表達式

for c in "word": 
    print c 

我剛剛遇到一些使用for的例子。它們不是從for語句開始,而是在表達式的末尾標記它(而不涉及縮進的代碼塊)。例如:

sum(x*x for x in range(10)) 

任何人都可以指向我的一些文件,概述了這種使用for?我一直能找到例子,但沒有解釋。我所能找到的所有for文檔都描述了以前的使用(塊代碼示例)。我甚至不知道該怎麼稱呼這個用途,所以如果我的問題標題不清楚,我很抱歉。

回答

15

你指的是Python中的Generator。看看: -

參見文檔: - Generator Expression包含正是你已經張貼

從文檔相同的例子: -

生成器是創建迭代器的簡單而強大的工具。他們 是像常規函數一樣編寫的,但是隻要他們想返回數據就使用yield語句 。接下來的每次()被調用時, 發電機暫停處繼續關閉(它記憶所有的數據值 和語句最後執行)

發電機是類似於你square brackets而不是使用List Comprehensionbrackets,但它們更有記憶效率。它們不會同時返回結果的完整list,但它們會返回生成器對象。無論何時調用generator對象上的next(),生成器都使用yield返回下一個值。

List Comprehension上面的代碼看起來像: -

[x * x for x in range(10)] 

您還可以添加條件,在爲年底篩選出的結果。

[x * x for x in range(10) if x % 2 != 0] 

這將在範圍爲1返回乘以2的numbers列表到5,如果數量不能被2整除。

描繪了使用yieldGenerators一個例子可以是: -

def city_generator(): 
    yield("Konstanz") 
    yield("Zurich") 
    yield("Schaffhausen") 
    yield("Stuttgart") 

>>> x = city_generator() 
>>> x.next() 
Konstanz 
>>> x.next() 
Zurich 
>>> x.next() 
Schaffhausen 
>>> x.next() 
Stuttgart 
>>> x.next() 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
StopIteration 

所以,你看,爲了next()每次調用執行generator下一個yield()。最後它拋出StopIteration

+1

發電機和還列表解析,這看起來非常相似:'[X * X爲在範圍X(10)]'。還可以包括篩選出的結果的條件:'[X * X爲如果x%2 == 0或x%3 == 0在範圍(10)X]'。 –

4

這些都是generator expressions和它們與list comprehensions

列表解析允許輕鬆創建列表。例如,如果你想創造完美的正方形的列表,你可以這樣做:

>>> squares = [] 
>>> for x in range(10): 
...  squares.append(x**2) 
... 
>>> squares 
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81] 

但相反,您可以使用列表理解:

squares = [x**2 for x in range(10)] 

發電機表情都像列表解析,除非他們返回一個生成器對象而不是一個列表。可以遍歷以類似的方式列出推導這個生成器對象,但你不必存儲在內存中的整個列表一次,因爲你想,如果你在一個列表理解創建的列表。