Seite 1 von 1

Python 2.5 -> 2.6: Länge eines reversed()-Iterators

Verfasst: Samstag 2. Mai 2009, 22:19
von Dauerbaustelle
Hab ich da was nicht mitbekommen? len(reversed(...)), welches unter Python 2.5 funktioniert...:

Code: Alles auswählen

#Python 2.5.2 (r252:60911, Jul 31 2008, 17:28:52)
In [1]: len(reversed(range(5)))
Out[1]: 5
... funktioniert mit 2.6 nicht mehr:

Code: Alles auswählen

#Python 2.6.2 (release26-maint, Apr 19 2009, 01:56:41) 
In [1]: len(reversed(range(5)))
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)

/home/jonas/<ipython console> in <module>()

TypeError: object of type 'listreverseiterator' has no len()
Hm.

Verfasst: Samstag 2. Mai 2009, 22:24
von OverNord
Also mit 2.6.1 funktioniert es.

Verfasst: Samstag 2. Mai 2009, 22:30
von birkenfeld
Iteratoren haben keine Länge, insofern ist die Änderung richtig.

Das in 2.6.1 -> 2.6.2 zu ändern, war vielleicht weniger günstig :)

Verfasst: Samstag 2. Mai 2009, 22:49
von Dauerbaustelle
birkenfeld hat geschrieben:Iteratoren haben keine Länge, insofern ist die Änderung richtig.
Hm... das ist eigentlich ziemlich unpraktisch, zumal bei solche trivialen Iteratoren wie `reversed(iterable)` die Länge von `iterable` gleich der Länge von `reserved(iterable)` wäre... Kommt man denn von `reversed(iterable)` irgendwie auf `iterable`?

Verfasst: Samstag 2. Mai 2009, 22:55
von birkenfeld
Nein, denn Iteratoren haben im Allgemeinen auch kein "iterable", aus dem sie erzeugt werden.

Verfasst: Samstag 2. Mai 2009, 22:57
von BlackJack
@Dauerbaustelle: Das die Länge von "iterabel" abhängt ist zwar richtig, aber auch die ist ja nicht zuverlässig immer bekannt solange man das "iterable" nicht komplett durchläuft, wie soll `reversed` das also können!?

Man könnte sich zum Beispiel eine Art Datenbankcursor vorstellen, der die Daten erst auf Anfrage liefert und es ermöglicht auch in umgekehrter Reihenfolge zu liefern, indem er dass der Datenbank so sagt. In dem Fall würde die DB-Software das "umdrehen" übernehmen und man wüsste erst wie viele Elemente vorhanden sind, wenn man wirklich alle ausgelesen hat.

Verfasst: Samstag 2. Mai 2009, 22:58
von Dauerbaustelle
Schon, aber jetzt mal von Listen oder Tuples oder so ausgehend... Hm. Wie bereits gefragt, komme ich von einem Generator auf das Original-Iterable?

Verfasst: Samstag 2. Mai 2009, 23:11
von Leonidas
Dauerbaustelle hat geschrieben:Wie bereits gefragt, komme ich von einem Generator auf das Original-Iterable?
Gar nicht, aber du kannst einen Iterator in eine Liste oder ein Tupel "expandieren" lassen. Die wiederrum eine Länge haben.

Noch spaßiger wird es mit ``len(reversed(itertools.count(0)))`` - was wäre denn da die Länge? Spätestens ab hier hat man ein logisches Problem.

Verfasst: Samstag 2. Mai 2009, 23:14
von str1442
Nein. Iteratoren sind doch die grundlegenden Objekte fürs Iterieren. Sie sind darauf ausgelegt, bloß das zu tun, und zwar vornehmlich aus irgendwelchen "Streams". Listen und Tupel machen nur Gebrauch von Iteratoren. Das sie eine feste Länge haben ist eine Eigenschaft der Listen / Tupel, Iteratoren wissen nur, wie sie ihre einzelnen Objekte bekommen, niemals wie viele es sind. Würde ein Iterator vermuten, wie "lang" er ist, wüsste er etwas, was er nicht wissen darf, da das Konzept von Länge ja so direkt in ihm nicht existiert. Er weiß noch nichtmal, das es Dinge mit festen Längen gibt. Wenn ich es mir recht überlege, darf er noch nichtmal wissen, das es überhaupt Dinge gibt. Man kann allerdings eigene Iteratoren schreiben, die eine Länge haben. Das grundlegende Konzept ist aber imho gut so.