2013-02-08 30 views
0

這工作得很好:生成器陷入列表理解中的無限循環?

>>> def my_range(stop): 
    i = 0 
    while i < stop: 
     yield i 
     i += 1 

>>> [k for k in my_range(10) if k < 5] 
[0, 1, 2, 3, 4] 

現在我修改我的發電機:

>>> def my_range(): 
    i = 0 
    while True: 
     yield i 
     i += 1 

>>> result = [] 
>>> for k in my_range(): 
    if k < 5: 
     result.append(k) 
    else: 
     break 


>>> print(result) 
[0, 1, 2, 3, 4] 

現在,這是爲什麼被困在一個無限循環?即使我有k < 5.生成器是否應該只在下一次被調用時進行迭代?

>>> [k for k in my_range() if k < 5] 

回答

7

當它返回false時,LC中的條件並不意味着break;如果你想要這種行爲,然後看看itertools,特別是takewhile()

6

This answer解釋說得好:

請記住以下幾點:

[ expression for item in list if conditional ] 

等同於:

for item in list: 
    if conditional: 
     expression 

這意味着你的列表理解:

[k for k in my_range() if k < 5] 

等同於:

for k in my_range(): 
    if k < 5: 
     k 

現在應該很清楚爲什麼這個從未終止:沒有什麼實際break無限循環。

+0

明白了,非常感謝。 – jurgenreza

+0

有沒有辦法讓'break'並讓列表理解停止從發生器獲取值?最好不使用'itertools' – Michael

+0

@Michael爲什麼不使用'itertools'? –