2009-06-20 20 views
28

Was ist der Unterschied zwischen einem Iterator und einem Generator?Was ist der Unterschied zwischen einem Iterator und einem Generator?

+1

Ich selbst bin Tritte Spur meiner Kopie zu verlieren von Griswolds Buch über die Programmiersprache Icon. Soweit ich weiß, sind Iteratoren und Generatoren zuerst als Sprachmerkmale aufgetaucht, und die Erklärungen waren großartig. Natürlich war das vor über 20 Jahren und ich dachte mir, dass sie niemals in irgendeiner Sprache auftauchen würden, die ich tatsächlich in der Produktion verwenden würde. Aber jetzt sind sie in Python und kommen zu JavaScript, also habe ich mich geirrt. – Nosredna

+1

Ähnlich: [Unterschied zwischen Pythons Generatoren und Iteratoren] (http://stackoverflow.com/q/2776829/55075), aber für Python-spezifisch. – kenorb

Antwort

34

Generatoren sind Iteratoren, aber nicht alle Iteratoren sind Generatoren.

Ein Iterator ist in der Regel etwas, das eine nächste Methode hat, um das nächste Element aus einem Stream zu erhalten. Ein Generator ist ein Iterator, der an eine Funktion gebunden ist.

Zum Beispiel ein Generator in Python:

def genCountingNumbers(): 
    n = 0 
    while True: 
    yield n 
    n = n + 1 

Dies hat den Vorteil, dass Sie nicht brauchen, unendliche Zahlen im Speicher speichern über sie zu wechseln.

würden Sie verwenden diese wie jede Iterator:

for i in genCountingNumbers(): 
    print i 
    if i > 20: break # Avoid infinite loop 

Sie auch ein Array iterieren könnte:

for i in ['a', 'b', 'c']: 
    print i 
5

Ein Generator ist eine Implementierung eines Iterators. Es ist in der Regel eine Routine, die ihrem Aufrufer mehrere Werte liefert, im Gegensatz zu nur einem.

in C#

// yield-example.cs 
using System; 
using System.Collections; 
public class List 
{ 
    public static IEnumerable Power(int number, int exponent) 
    { 
     int counter = 0; 
     int result = 1; 
     while (counter++ < exponent) 
     { 
      result = result * number; 
      yield return result; 
    } 
} 

static void Main() 
{ 
    // Display powers of 2 up to the exponent 8: 
    foreach (int i in Power(2, 8)) 
    { 
     Console.Write("{0} ", i); 
    } 
} 
} 

See Wikipedia's entry

37

Ein iterator quert eine Sammlung eines nach dem anderen.

Eine generator generiert eine Sequenz, ein Element zu einer Zeit.

Sie zum Beispiel könnte, iterieren das Ergebnis eines Generators ...

0

Normalerweise gehen Iteratoren über eine bestehende Sequenz (wie ein Array oder eine Liste) und Generatoren berechnen einen neuen Wert bei jeder Anfrage.

+0

Das ist nicht richtig. Es ist möglich, (ohne einen Generator) einen Iterator zu machen, der zum Beispiel das Quadrat jeder natürlichen Zahl liefert. Es gibt kein Array oder Listenobjekt, das dies unterstützt. –

+0

Wenn Sie das als Iterator bezeichnen, was ist der Unterschied zwischen einem Iterator und einem Generator? –

+0

Der Unterschied ist im Grunde, was unbekannt (google) sagte. Ein "Generator ist ein Iterator, der an eine Funktion gebunden ist". Natürlich ist die "Funktion" wirklich eine Zustandsmaschine, die wie eine Funktion aussieht. Ich habe ein Beispiel in einer Antwort angegeben. –

0

Ein Iterator wird normalerweise verwendet, um sich durch eine Sammlung von Elementen zu bewegen. Oft mit MoveNext() und Current() Methoden. MoveNext() würde den Zeiger (falls möglich) zum nächsten Sammlungselement verschieben und basierend auf dem Erfolg Wahr/Falsch zurückgeben. Current() würde den tatsächlichen Wert liefern.

Ein Generator ist eine Implementierung von Iterator, aber anstatt auf eine bereits vorhandene Sammlung zu verweisen, erstellt er neue Elemente bei jedem MoveNext() - Aufruf.

1

Ein Iterator wird verwendet, um über die Objekte in einer Sammlung zu iterieren, sei es ein Array, eine verkettete Liste, eine Struktur, eine Hash-Map oder was auch immer. Du hast eine Menge Objekte und willst mit jedem etwas machen.

Ein Generator gibt nicht nur die Objekte aus einer endlichen Sammlung von Objekten zurück. Stattdessen erzeugt es sie im laufenden Betrieb. Sie könnten es als Iterator über eine Sammlung konzeptualisieren, die erstellt wird, während Sie darüber iterieren und möglicherweise keine endliche Größe haben.

Zum Beispiel könnten Sie einen Generator haben, der Primzahlen von 2 bis unendlich spuckt. Es gibt keine Möglichkeit, eine Sammlung von "allen Primzahlen" zu haben und mit einem Iterator darüber zu iterieren. Du brauchst einen Generator.

Oder Sie könnten einen Generator haben, der eine Ganzzahl nimmt und die Faktoren dieser Zahl zu einem Zeitpunkt liefert. Ein Generator würde hier von Vorteil sein, da Sie die Faktoren eins nach dem anderen untersuchen könnten, ohne Speicher für alle Faktoren im Voraus zu reservieren. Sie können sie auch so verwenden, wie sie generiert werden, anstatt die gesamte Liste im Voraus erstellen zu müssen, was möglicherweise langsamer als gewünscht ist. Hier ist ein Beispiel für einen solchen Generator in Python:

def factors(n): 
    for i in xrange(1, n+1): 
     if n % i == 0: 
      yield i 

for n in factors(1234567890): 
    print n 

Wenn Sie dies ausführen, um die Faktoren sehen können gedruckt, wie sie berechnet werden. Wir brauchen nicht wirklich eine vollständige Liste aller Faktoren im Speicher zu führen.

+1

Auch dies ist falsch. Iteratoren müssen keine "echte" Backing-Sammlung haben (Array, verknüpfte Liste, was auch immer). –

4

Ein Generator ist eine spezielle Funktion, die sich wie ein Iterator verhalten kann und bei jedem Aufruf einen Wert zurückgibt. Weil es eine Funktion ist, kann es jeden Wert bei Bedarf berechnen. Und weil es speziell ist, kann es sich an seinen Zustand erinnern, seit es das letzte Mal aufgerufen wurde, und der resultierende Code sieht ziemlich einfach aus.

Zum Beispiel wird dieser Generator in Python eine Folge von ganzen Zahlen

def integers(): 
    int n = 0 
    while True: 
     yield n 
     n += 1 

Das Wichtigste in diesem Beispiel erzeugt die yield n Aussage. Die Funktion gibt den Wert zurück, und wenn sie das nächste Mal aufgerufen wird, wird sie von diesem Punkt aus fortgesetzt.

Dieser Link hat eine längere Erklärung von Generatoren in Python: link text

6

Hier gibt es zu viel Python ist, und zu viele Leute, die sagen Generatoren sind die nur Weise eine unendliche Iterator zu implementieren. Hier ist das Beispiel, das ich erwähnt habe (Quadrate aller natürlichen Zahlen), das in C# implementiert wurde. ExplicitSquares implementiert explizit einen Iterator (in C# IEnumerator genannt). ImplicitSquares verwendet einen Generator, um das Gleiche zu tun. Beide sind unendliche Iteratoren und haben keine Backing-Sammlung. Der einzige Unterschied besteht darin, ob die Zustandsmaschine ausgeschrieben ist oder alternativ ein Generator verwendet wird.

using System.Collections; 
using System.Collections.Generic; 
using System; 

class ExplicitSquares : IEnumerable<int> 
{ 
    private class ExplicitSquaresEnumerator : IEnumerator<int> 
    { 
     private int counter = 0; 

     public void Reset() 
     { 
      counter = 0; 
     } 

     public int Current { get { return counter * counter; }} 

     public bool MoveNext() 
     { 
      counter++; 
      return true; 
     } 

     object IEnumerator.Current { get { return Current; } } 

     public void Dispose(){} 
    } 

    public IEnumerator<int> GetEnumerator() 
    { 
     return new ExplicitSquaresEnumerator(); 
    } 

    IEnumerator IEnumerable.GetEnumerator() 
    { 
     return GetEnumerator(); 
    } 
} 

class ImplicitSquares : IEnumerable<int> 
{ 
    public IEnumerator<int> GetEnumerator() 
    { 
     int counter = 1; 
     while(true) 
     { 
      int square = counter * counter; 
      yield return square; 
      counter++; 
     } 
    } 

    IEnumerator IEnumerable.GetEnumerator() 
    { 
     return GetEnumerator(); 
    } 
} 

public class AllSquares 
{ 
    private static readonly int MAX = 10; 

    public static void Main() 
    { 
     int i = 0; 
     foreach(int square in new ExplicitSquares()) 
     { 
      i++; 
      if(i >= MAX) 
       break; 
      Console.WriteLine(square); 
     } 

     Console.WriteLine(); 

     int j = 0; 
     foreach(int square in new ImplicitSquares()) 
     { 
      j++; 
      if(j >= MAX) 
       break; 
      Console.WriteLine(square); 
     } 
    } 
} 
2

(von JavaScript useland, aber wie alle anderen)

Ein interator ein Objekt ist, das eine .next() Funktion

Ein Generator hat, ist eine Funktion einmal aufgerufen, erzeugen einen Iterator, es ist eine Fabrik für Iterator.

In Javascript, Generatorfunktion erfordert eine spezielle Syntax-Funktion *() {} und die Verwendung für die Ausbeute Schlüsselwort

See MDN dazu: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Iterators_and_Generators

Verwandte Themen