Wie man einen Generator durchläuft

80

Wie kann man einen Generator durchlaufen? Ich dachte so:

gen = function_that_returns_a_generator(param1, param2)
if gen: # in case the generator is null
    while True:
        try:
            print gen.next()
        except StopIteration:
            break

Gibt es einen pythonischeren Weg?

iTayb
quelle
Ich würde vorschlagen, zu verwenden break; nichtcontinue
Jon Clements
Ich würde es tatsächlich so machen, wenn der Generator eine Ausnahme auf ein Element auslöst, Sie aber die Iteration nicht stoppen möchten.
Robbrit

Antworten:

144

Einfach

for x in gen:
    # whatever

wird den Trick machen. Beachten Sie, dass if genimmer zurückgegeben wird True.

Sven Marnach
quelle
6
Nein, if genkehrt nicht immer zurück True. Wenn die Operation function_that_returns_a_generator()zurückkehrt None, wird in der Anweisung genausgewertet . Falseif
Drevicko
44
@drevicko: Ich habe angenommen, dass function_that_returns_a_generator()ein Generator zurückgegeben wird (kühne Annahme, nicht wahr ?). Noneist kein Generator.
Sven Marnach
Da scheint diese Antwort fragt OP für eine „pythonic Weg“, ziemlich echt, da Python befürwortet EAFP ;-)
DerMike
17
for item in function_that_returns_a_generator(param1, param2):
    print item

Sie müssen sich keine Gedanken über den Test machen, um festzustellen, ob von Ihrer Funktion etwas zurückgegeben wird, als ob nichts zurückgegeben wird. Sie werden nicht in die Schleife eintreten.

Christian Witts
quelle
9

Falls Sie die Leistung des Generators nicht benötigen, weil Sie sich nur um seine Nebenwirkungen kümmern, können Sie den folgenden Einzeiler verwenden:

for _ in gen: pass
mmj
quelle
3
oder einfachlist(gen)
am
6

Sie können es einfach durchlaufen:

>>> gen = (i for i in range(1, 4))
>>> for i in gen: print i
1
2
3

Beachten Sie jedoch, dass Sie nur einmal eine Schleife durchführen können. Das nächste Mal ist der Generator leer:

>>> for i in gen: print i
>>> 
Wojciech Kałuski
quelle
4

Behandle es einfach wie jedes andere iterable:

for val in function_that_returns_a_generator(p1, p2):
    print val

Beachten Sie, dass dies if gen:immer True ist, es ist also ein falscher Test

Jon Clements
quelle
2

Wenn Sie sich manuell durch den Generator bewegen möchten (dh manuell mit jeder Schleife arbeiten möchten), können Sie Folgendes tun:

    from pdb import set_trace

    for x in gen:
        set_trace()
        #do whatever you want with x at the command prompt
        #use pdb commands to step through each loop of the generator e.g., >>c #continue   
rysqui
quelle
1
von pdb import set_trace # no () :)
Vlad K.
1

Die anderen Antworten sind gut für komplizierte Szenarien. Wenn Sie die Elemente einfach in eine Liste streamen möchten:

x = list(generator)

(oder, wenn Sie nur den Generator auslösen möchten, um Dinge zu tun, einfach list(generator).

Verwenden Sie für eine einfache Vorverarbeitung Listenverständnisse:

x = [tup[0] for tup in generator]

Oder wenn Sie einfache Funktionen ausführen möchten:

# didn't assign to variable b/c we don't care about what the print() function returns
[print(x) for x in gen]
Crypdick
quelle