2009-03-31 7 views
2

Viele Methoden, die verwendet zurückkehren Listen in Python 2.x jetzt scheinen zurückzukehren Iteratoren in Py3kPy3k Speicher Erhaltung von Iteratoren statt Listen

sind Iteratoren auch Ausdrücke Generator zurückkehrt? Faule Bewertung?

Damit wird der Speicherbedarf von Python drastisch reduziert werden. Ist es nicht?

Was ist mit den von 2to3 mit dem eingebauten Skript konvertierten Programmen?

Konvertiert das integrierte Tool explizit alle zurückgegebenen Iteratoren aus Gründen der Kompatibilität in Listen? Wenn dies der Fall ist, ist der geringere Speicherbedarf von Py3k in den konvertierten Programmen nicht wirklich offensichtlich. Ist es?

Antwort

7

Viele von ihnen sind nicht genau Iteratoren, sondern spezielle Ansichtsobjekte. Zum Beispiel gibt range() jetzt etwas zurück, das dem alten xrange-Objekt ähnlich ist - es kann immer noch indiziert werden, aber konstruiert die Ganzzahlen nach Bedarf.

Ähnlich dict.keys() gibt ein dict_keys-Objekt, das eine Ansicht auf dem Dict implementiert, statt eine neue Liste mit einer Kopie der Schlüssel zu erstellen.

Wie sich das auf Speicherabdrücke auswirkt, hängt wahrscheinlich vom Programm ab. Sicherlich gibt es mehr Betonung auf die Verwendung von Iteratoren, außer Sie brauchen wirklich Listen, wohingegen die Verwendung von Listen im Allgemeinen der Standardfall in python2 ist. Dies wird dazu führen, dass das durchschnittliche Programm wahrscheinlich speichereffizienter ist. Fälle, in denen es wirklich große Einsparungen gibt, werden wahrscheinlich bereits als Iteratoren in Python2-Programmen implementiert, da eine wirklich große Speicherbelegung hervorstechen wird und eher wahrscheinlich bereits angesprochen wird. (z. B. der Datei-Iterator ist bereits viel mehr Speicher effizienter als die ältere file.readlines() Methode)

Konvertieren wird von der 2to3-Tool durchgeführt, und wird in der Regel Dinge wie range() zu Iteratoren konvertieren, wo es sicher eine echte Liste isn bestimmen kann ‚t benötigt, so Code wie:

for x in range(10): print x 

auf den neuen Bereich() Objekt wechseln wird, nicht mehr eine Liste erstellen, und so wird erhalten, um den reduzierten Speicher Nutzen, aber Code wie:

x = range(20) 

wird wie folgt konvertiert:

x = list(range(20)) 

wie der Konverter nicht wissen kann, ob der Code ein in x echten Liste Objekt erwartet.

1

Sind Iteratoren auch Generatorausdrücke? Faule Bewertung?

Ein Iterator ist nur ein Objekt mit einer nächsten Methode. Was die Dokumentation die meiste Zeit bedeutet, wenn man sagt, dass eine Funktion einen Iterator zurückgibt, ist, dass ihr Ergebnis faul geladen ist.

Damit wird der Speicherbedarf von Python drastisch reduziert. Ist es nicht?

Kommt drauf an. Ich würde vermuten, dass das durchschnittliche Programm einen Unterschied nicht bemerken würde.Die Leistungsvorteile von Iteratoren gegenüber Listen sind nur dann von Bedeutung, wenn Sie einen großen Datensatz haben. Vielleicht möchten Sie this question sehen.

0

Einer der größten Vorteile von Iteratoren gegenüber Listen ist nicht der Arbeitsspeicher, sondern die Rechenzeit. Zum Beispiel in Python 2:

for i in range(1000000): # spend a bunch of time making a big list 
    if i == 0: 
     break # Building the list was a waste since we only looped once 

Jetzt nehmen Sie zum Beispiel:

for i in xrange(1000000): # starts loop almost immediately 
    if i == 0: 
     break # we did't waste time even if we break early 

Obwohl das Beispiel gekünstelt ist, ist der Anwendungsfall nicht: Schleifen werden häufig aus halbem Weg gebrochen. Eine ganze Liste zu erstellen, um nur einen Teil davon zu verwenden, ist eine Verschwendung, es sei denn, Sie verwenden sie mehr als einmal. Wenn dies der Fall ist, können Sie explizit eine Liste erstellen: r = list(range(100)). Aus diesem Grund sind Iteratoren in Python 3 an mehreren Stellen Standard; Sie haben nichts heraus, da Sie nach wie vor explizit Listen (oder andere Container) erstellen können. Aber Sie werden nicht dazu gezwungen, wenn Sie nur einmal iterieren wollen (was ich als den viel häufigeren Fall bezeichnen würde).