Frage

Ich bin ein großer Fan von Python für ... else Syntax - es ist erstaunlich, wie oft es ist anwendbar, und wie effektiv es Code vereinfachen

.

Allerdings habe ich nicht einen schönen Weg gefunden, es in einem Generator zu verwenden, zum Beispiel:

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

Im obigen Beispiel, würde Ich mag die print Anweisung nur dann ausgeführt werden, wenn i leer. Doch wie else nur break und return respektiert wird immer ausgeführt, unabhängig von der Länge der i.

Wenn es unmöglich for...else auf diese Weise zu verwenden, was ist der beste Ansatz, um dies so, dass die print Anweisung nur dann ausgeführt wird, wenn nichts nachgegeben wird?

War es hilfreich?

Lösung

Sie brechen die Definition eines Generators, der eine StopIteration Ausnahme auslösen soll, wenn Iteration abgeschlossen ist

(die automatisch durch eine Rückrechnung in einer Generatorfunktion behandelt wird)

So:

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

Bester der aufrufende Code behandeln den Fall eines leeren Iterator lassen:

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

Könnte ein sauberer Weg, um die oben zu tun, aber das sollte gut funktionieren, und fällt nicht in eine der gemeinsamen ‚Behandlung einen Iterators wie eine Liste‘ Fallen unten.

Andere Tipps

Es gibt ein paar Möglichkeiten, dies zu tun. Sie können immer die Iterator direkt verwenden:

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()

Aber wenn Sie mehr darüber wissen, was aus dem Argumente i zu erwarten, können Sie mehr prägnant sein:

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

einige der früheren Antworten zusammenfassend, könnte es wie folgt gelöst werden:

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

    if empty:
        print "empty"

so gibt es wirklich keine "else" Klausel beteiligt.

Wie Sie beachten, erkennt for..else nur eine break. So ist es nur anwendbar, wenn Sie nach etwas suchen und dann Stop .

Es ist nicht für Ihren Zweck nicht, weil es ein Generator, aber , da Sie alle Elemente verarbeiten, ohne zu stoppen (weil Sie wollen, dass sie alle erhalten, aber das ist nicht der Punkt).

So Generator oder nicht, müssen Sie wirklich ein boolean, wie in Ber-Lösung.

  
    

Wenn es unmöglich ist, zu verwenden für ... sonst auf diese Weise, was ist der beste Ansatz, um dies so, dass die Print-Anweisung nur dann ausgeführt wird, wenn nichts nachgegeben wird?

  

Maximale ich mir vorstellen kann:


>>> 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
>>>

Was ist einfache if-else?

def iterate(i):
    if len(i) == 0: print 'i is empty'
    else:
        for value in i:
            yield value
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top