2016-05-17 52 views
4
my_nums =(i*i for i in [1,2,3,4,5]) 
for k in (my_nums): 
    print(k) 
GG = list(my_nums) 

print(GG) 

它打印:蟒蛇基層發電機和列表的問題

1 
4 
9 
16 
25 
[] 

Process finished with exit code 0 

我不明白爲什麼[]空值(它應該是[1,4,9,16,25])?另外,for-loop是否將生成器值轉換爲列表?

回答

4

下面是一個generator comprehension:你循環

my_nums =(i*i for i in [1,2,3,4,5]) 

for k in (my_nums): 
    print(k) 

所以首次超過它,並打印值,生成打印每它可以產生價值。 for循環的工作方式是調用my_nums.next()並將獲得的值分配給k,然後打印出來。 for循環的迭代在引發StopIteration異常時停止。

而且,當您在for循環之後使用GG = list(my_nums)時,您會得到一個空列表,因爲生成器已經耗盡,並且沒有任何東西可以生成。

如果要由發電機產生的值存儲到list你可以直接做到這一點如下:

my_nums =(i*i for i in [1,2,3,4,5]) 
GG = list(my_nums) # no for loop for printing it already 

雖然,我不知道,在性能方面,你會如果你獲得任何優勢它如上所述。

+1

明白了!謝謝senpai! –

0

當您迭代生成器時,您同時清空它。 所以,只需刪除for k in (my_nums): print(k),你就會得到預期的結果。

同樣的事情在這裏:

my_nums =(i*i for i in [1,2,3,4,5]) 
a = list(my_nums) 
b = list(my_nums) 
print(a) 
// [1,4,9,16,25] 
print(b) 
// [] 
0

那是因爲你已經用盡了所有生成的值,當你做了

for k in (my_nums): # you already made my_nums generate till the end here 
    print(k) 

認爲發生器爲從流中讀取。您已經閱讀了流,因此當您嘗試從已經耗盡的發生器讀取更多數據時,您會看到一個空列表

1

僅僅因爲您剛剛第一次用完發生器!

my_nums = (i*i for i in [1,2,3,4,5]) 
for k in my_nums: 
    print(k) 

my_nums = (i*i for i in [1,2,3,4,5]) 
print(list(my_nums)) 
0

生成表達式所示:

my_nums = (item for item in [1, 2, 3, 4, 5, 6, 7]) 

是這樣的事情語法糖:

def generator(iterable): 
    for item in iterable: 
     yield item 

my_nums = generator([1, 2, 3, 4, 5, 6, 7]) 

的for循環本身等同於這樣的事:

while True: 
    try: 
     item = next(my_nums) 
    except StopIteration: 
     break 
    else: 
     print(item) 

gg = list(iterable)是一樣的東西:

gg = [] 
for item in my_nums: 
    gg.append(item) 

的問題是,在發電機表達你第一次循環,它耗盡。如果您嘗試再次循環播放它,它只會提高StopIteration並打破循環。

例如:

>>> my_nums = (i for i in [1, 2]) 
>>> list(my_nums) 
[1, 2] 
>>> list(my_nums) 
[] 
>>> next(my_nums) 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
StopIteration 
>>> 

見你打電話list(my_nums)第二次如何返回一個空列表?這是因爲發電機耗盡。你可以看到它如何提高StopIteration,如果你嘗試從中獲取下一個項目。

0

生成器是迭代器,但是你只能遍歷它們一次。這是因爲他們沒有將所有的值存儲在內存中,他們在運行中生成值。

my_nums =(i*i for i in [1,2,3,4,5]) 
for k in (my_nums): 
    print(k) 

它打印:

1 
4 
9 
16 
25 

這僅僅是除非你使用()一樣,而不是[]。但是,由於發電機只能使用一次,所以不能再次執行for k in my_nums:它們計算1,然後將其忽略並計算4,並逐個計算25。

如果您嘗試再次執行迭代,則會得到StopIteration回溯。

這已在此thread上詳細討論過。