2016-10-20 4 views
17

ein Tupel Umkehren und eine Liste zurückgibt Objekte unterschiedlicher Art Umkehrung:Was ist der Unterschied zwischen einem umgekehrten Tupel und einer umgekehrten Liste?

>>> reversed((1,2)) 
<reversed at 0x7fffe802f748> 
>>> reversed([1,2]) 
<list_reverseiterator at 0x7fffebdd4400> 

Sie haben die gleiche dir. Kein Typ ist eine Unterklasse des anderen.

Warum ist das? Was kann man tun, was der andere nicht kann?

+0

Es scheint keinen Unterschied bar Leistung zu geben, es sei denn, Sie verwenden eine ältere Version von Python, wo Sie len auf dem listreverseterator aufrufen könnten. http://bugs.python.org/issue3689. –

Antwort

12

Grundsätzlich ist eine Liste implementiert die __reversed__ Methode und gibt ein spezialisiertes Objekt, während tuple für jede Folge auf die Standardimplementierung von reversed fällt zurück:

>>> list.__reversed__ 
<method '__reversed__' of 'list' objects> 
>>> tuple.__reversed__ 
AttributeError: type object 'tuple' has no attribute '__reversed__' 

Nun, warum Liste nicht auf die Sequenz Zu reversed Objekt muss im Quellcode für das Listenobjekt selbst gefunden werden - wahrscheinlich ermöglicht es einige Optimierungen durch direkten Zugriff auf einige der internen list Attribute.

Eigentlich an dem C-Code sucht, gibt es kaum einen Unterschied, und schon gar nichts, das ins Auge fällt -

ich die besondere Liste zu sagen wagen würde __reversed__ Implementierung ist ein Rest von Python2 Tagen, wo reversed würde eigentlich jede andere Python-Sequenz in eine list kopieren - so würde es keinen Sinn für andere Sequ Es gibt spezielle Fälle dafür (und wenn sie das allgemeine enumreverse implementiert haben, war es gerade gut genug für Tupel).

Ich bin mir ziemlich sicher, dass, wenn man einfach die __reversed__ Slot Kommentar heraus listobject.c würde, Python und seine Listen funktionieren würde, als ob nichts geschehen wäre, reversed auf den allgemeinen Fall in Verzug.

+3

Standardmäßig umgekehrt: https://github.com/python/cpython/blob/master/Objects/enumobject.C# L230 Liste umgekehrt: https://github.com/python/cpython/blob/master/Objects/listobject.c#L2823 – BlackBear

+3

Was kann man tun, dass der andere nicht kann? – wim

+5

** Github pro-tip **: Wenn Sie eine Verknüpfung zu einer Zeilennummer in blob/master erstellen, werden die Links gelöscht, sobald die Datei geändert wird. Wählen Sie stattdessen die gewünschten Zeilen und drücken Sie dann die Taste "y", um die Verknüpfung zu einem bestimmten Commit festzulegen. Dann wird die Zeilennummer niemals vom relevanten Code abweichen. Ich habe die Links in Ihrer Antwort aktualisiert. – wim

4

Nach Pythons documentation:

object.__reversed__(self)

aufgerufen (falls vorhanden) durch die reversed() eingebaute in Iteration umkehren zu implementieren. Es sollte ein neues Iteratorobjekt zurückgeben, das alle Objekte im Container in umgekehrter Reihenfolge über iteriert.

Wenn die __reversed__() Verfahren nicht vorgesehen ist, die reversed() Einbau-wird unter Verwendung der Sequenz-Protokoll zurückfallen (__len__() und __getitem__()). Objekte, die das Sequenzprotokoll unterstützen, sollten nur __reversed__() bereitstellen, wenn sie eine Implementierung bereitstellen können, die effizienter ist als die, die von reversed() bereitgestellt wird.

+3

Es scheint seltsam, dass die Liste eine effizientere Implementierung zur Verfügung hätte, aber Tupel nicht. – wim

+0

ja genau: D @wim –

Verwandte Themen