簡體   English   中英

在Python生成器中使用for…else

[英]Using for…else in Python generators

我是Python的... else語法的忠實擁護者 -令人驚訝的是它的應用頻率以及簡化代碼的有效性。

但是,我還沒有找到在生成器中使用它的好方法,例如:

def iterate(i):
    for value in i:
        yield value
    else:
        print 'i is empty'

在上面的示例中,我希望僅在i為空時才執行print語句。 然而,隨着else只有方面breakreturn ,它總是執行的長度無關, i

如果無法以這種方式for...else ,那么最好的方法是什么,以便僅在不產生任何結果時才執行print語句?

您正在破壞生成器的定義,該定義應在迭代完成時引發StopIteration異常(生成器函數中的return語句會自動處理該異常)

所以:

def iterate(i):
    for value in i:
        yield value
    return

最好讓調用代碼處理空迭代器的情況:

count = 0
for value in iterate(range([])):
    print value
    count += 1
else:
    if count == 0:
        print "list was empty"

可能是做上述事情的一種更清潔的方法,但是應該可以正常工作,並且不屬於下面常見的任何“像列表一樣處理迭代器”陷阱。

有兩種方法可以做到這一點。 您總是可以直接使用Iterator

def iterate(i):
    try:
        i_iter = iter(i)
        next = i_iter.next()
    except StopIteration:
        print 'i is empty'
        return

    while True:
        yield next
        next = i_iter.next()

但是,如果您對參數i期望的了解更多,則可以更加簡潔:

def iterate(i):
    if i:  # or if len(i) == 0
        for next in i:
            yield next
    else:
        print 'i is empty'
        raise StopIteration()

如您所述, for..else僅檢測到break 因此,它僅在您尋找某物然后停止時才適用。

它不是適用於您的目的,不是因為它是生成器,而是因為您想處理所有元素而不停止 (因為您想產生所有元素 ,但這不是重點)。

不管是否生成器,就像Ber的解決方案中一樣,您確實需要布爾值。

總結一些較早的答案,可以這樣解決:

def iterate(i):
    empty = True
    for value in i:
        yield value
        empty = False

    if empty:
        print "empty"

因此,實際上沒有涉及“ else”子句。

如果無法以這種方式用於... else,那么最好的方法是什么,以便僅在不產生任何結果時才執行print語句?

我能想到的最大值:


>>> empty = True
>>> for i in [1,2]:
...     empty = False
... if empty:
...     print 'empty'
...
>>>
>>>
>>> empty = True
>>> for i in []:
...     empty = False
... if empty:
...    print 'empty'
...
empty
>>>

簡單的if-else呢?

def iterate(i):
    if len(i) == 0: print 'i is empty'
    else:
        for value in i:
            yield value

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM