Was macht das Generatorverständnis? Wie funktioniert es? Ich konnte kein Tutorial dazu finden.
Was macht das Generatorverständnis? Wie funktioniert es? Ich konnte kein Tutorial dazu finden.
Antworten:
Verstehst du Listenverständnis? Wenn ja, ist ein Generatorausdruck wie ein Listenverständnis, aber anstatt alle gewünschten Elemente zu finden und in eine Liste zu packen, wartet er und gibt jedes Element einzeln aus dem Ausdruck heraus.
>>> my_list = [1, 3, 5, 9, 2, 6]
>>> filtered_list = [item for item in my_list if item > 3]
>>> print(filtered_list)
[5, 9, 6]
>>> len(filtered_list)
3
>>> # compare to generator expression
...
>>> filtered_gen = (item for item in my_list if item > 3)
>>> print(filtered_gen) # notice it's a generator object
<generator object <genexpr> at 0x7f2ad75f89e0>
>>> len(filtered_gen) # So technically, it has no length
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: object of type 'generator' has no len()
>>> # We extract each item out individually. We'll do it manually first.
...
>>> next(filtered_gen)
5
>>> next(filtered_gen)
9
>>> next(filtered_gen)
6
>>> next(filtered_gen) # Should be all out of items and give an error
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
StopIteration
>>> # Yup, the generator is spent. No values for you!
...
>>> # Let's prove it gives the same results as our list comprehension
...
>>> filtered_gen = (item for item in my_list if item > 3)
>>> gen_to_list = list(filtered_gen)
>>> print(gen_to_list)
[5, 9, 6]
>>> filtered_list == gen_to_list
True
>>>
Da ein Generatorausdruck jeweils nur ein Element liefern muss, kann dies zu erheblichen Einsparungen bei der Speichernutzung führen. Generatorausdrücke sind in Szenarien am sinnvollsten, in denen Sie jeweils ein Element aufnehmen, viele Berechnungen basierend auf diesem Element durchführen und dann mit dem nächsten Element fortfahren müssen. Wenn Sie mehr als einen Wert benötigen, können Sie auch einen Generatorausdruck verwenden und jeweils mehrere Werte abrufen. Wenn Sie alle Werte benötigen, bevor Ihr Programm fortgesetzt wird, verwenden Sie stattdessen ein Listenverständnis.
next(...)
anstelle von .__next__()
in Python 3 verwenden.
If you need more than one value, you can also use a generator expression and grab a few at a time
. Könnten Sie bitte ein Beispiel für diese Verwendung geben? Vielen Dank.
Ein Generatorverständnis ist die träge Version eines Listenverständnisses.
Es ist wie ein Listenverständnis, nur dass es anstelle der Liste einen Iterator zurückgibt, dh ein Objekt mit einer next () -Methode, das das nächste Element liefert.
Wenn Sie mit Listenverständnissen nicht vertraut sind, finden Sie hier und für Generatoren hier .
Das Listen- / Generatorverständnis ist ein Konstrukt, mit dem Sie eine neue Liste / einen neuen Generator aus einer vorhandenen erstellen können.
Angenommen, Sie möchten die Liste der Quadrate jeder Zahl von 1 bis 10 generieren. Sie können dies in Python tun:
>>> [x**2 for x in range(1,11)]
[1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
Hier range(1,11)
wird die Liste generiert [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
, aber die range
Funktion ist kein Generator vor Python 3.0, und daher ist das Konstrukt, das ich verwendet habe, ein Listenverständnis.
Wenn ich einen Generator erstellen wollte, der dasselbe tut, könnte ich das so machen:
>>> (x**2 for x in xrange(1,11))
<generator object at 0x7f0a79273488>
In Python 3 handelt es sich jedoch range
um einen Generator, sodass das Ergebnis nur von der verwendeten Syntax abhängt (eckige Klammern oder runde Klammern).
Das Generatorverständnis ist eine einfache Möglichkeit, Generatoren mit einer bestimmten Struktur zu erstellen. Nehmen wir an, Sie möchten eine generator
, die nacheinander alle geraden Zahlen ausgibt your_list
. Wenn Sie es mit dem Funktionsstil erstellen, sieht es folgendermaßen aus:
def allEvens( L ):
for number in L:
if number % 2 is 0:
yield number
evens = allEvens( yourList )
Mit diesem Generatorverständnisausdruck können Sie dasselbe Ergebnis erzielen:
evens = ( number for number in your_list if number % 2 == 0 )
In beiden Fällen erhalten Sie beim Anruf next(evens)
die nächste gerade Nummer your_list
.
Das Generatorverständnis ist ein Ansatz zum Erstellen von Iterables, ähnlich einem Cursor, der sich auf einer Ressource bewegt. Wenn Sie den MySQL-Cursor oder den Mongodb-Cursor kennen, wissen Sie möglicherweise, dass die gesamten tatsächlichen Daten nie auf einmal, sondern einzeln in den Speicher geladen werden. Ihr Cursor bewegt sich hin und her, aber es befindet sich immer ein Element mit einer Zeile / Liste im Speicher.
Kurz gesagt, mithilfe des Generatorverständnisses können Sie problemlos Cursor in Python erstellen.
Ein weiteres Beispiel für das Verständnis des Generators:
print 'Generator comprehensions'
def sq_num(n):
for num in (x**2 for x in range(n)):
yield num
for x in sq_num(10):
print x