Zum Inhalt

Generatoren

Generatoren

Generatoren bieten eine effiziente Möglichkeit, Werte einzeln zu erzeugen, ohne die gesamte Sequenz im Speicher zu speichern.


Bereich vs. Liste

range(100)

def make_list(num):
    result = []
    for item in range(num):
        result.append(item * 2)
    return result

print(make_list(100))       # Using a custom function
print(list(range(100)))     # Using built-in range

Verwenden Sie einen Generator und generieren Sie diese tatsächlich, ohne Speicherplatz zu beanspruchen.

Iterables vs. Generatoren

  • Iterierbar → jedes Objekt, das Sie durchlaufen können.
    Es verfügt über eine Dunder-Iter-Methode.(iter)

  • Generator → ein spezieller Typ von Iterable, der mit yield erstellt wurde.

  • Alles, was ein Generator ist, ist iterierbar.

  • Sie können darüber iterieren, aber nicht alles, was iterierbar ist, ist ein Generator. Range ist ein Generator Liste ist iterierbar, aber kein Generator
  • Der Generator ist also eine Teilmenge einer Iteration

Erstellen eines Generators

def generator_func(num):
    for i in range(num):
        yield i             #a generator uses yield instead of return to make a generator

g = generator_func(1)
next(g)                     #if the range is out of num it gives error of stop iteration
print(next(g))              #can call generator with next, while iterating

for i in generator_func(1):
    print(i)

yield gibt die Werte einzeln zurück. next() ruft den nächsten Wert ab, bis StopIteration ausgelöst wird.

Implementieren einer benutzerdefinierten For-Schleife

def special_for(iterable):
    iterator = iter(iterable)
    while True:
        try:
            print(iterator)
            print(next(iterator))
        except StopIteration:
            break

special_for([1,2,3])            #the list is stored at same memory place

Benutzerdefinierte Generatorklasse (Bereichsfunktion)

class MyGen():
    current = 0
    def __init__(self, first, last):
        self.first = first
        self.last = last

    def __iter__(self):
        return self

    def __next__ (self):
        if MyGen.current < self.last:
            num = MyGen.current
            MyGen.current += 1
            return num
        raise StopIteration

gen = MyGen(0,100)
for i in gen:
    print(i)