Ich habe mehrere Python-Tutorials (zum Beispiel Dive Into Python) und die Sprachreferenz auf Python.org gelesen - ich verstehe nicht, warum die Sprache Tupel benötigt.
Tupel haben keine Methoden im Vergleich zu einer Liste oder einem Satz. Wenn ich ein Tupel in einen Satz oder eine Liste konvertieren muss, um sie sortieren zu können, was bringt es dann überhaupt, ein Tupel zu verwenden?
Unveränderlichkeit?
Warum kümmert es jemanden, wenn eine Variable an einem anderen Ort im Speicher lebt als zu dem Zeitpunkt, als sie ursprünglich zugewiesen wurde? Dieses ganze Geschäft der Unveränderlichkeit in Python scheint überbetont zu sein.
Wenn ich in C / C ++ einen Zeiger zuweise und auf einen gültigen Speicher zeige, ist es mir egal, wo sich die Adresse befindet, solange sie nicht null ist, bevor ich sie verwende.
Wann immer ich auf diese Variable verweise, muss ich nicht wissen, ob der Zeiger noch auf die ursprüngliche Adresse zeigt oder nicht. Ich überprüfe nur auf null und benutze es (oder nicht).
Wenn ich in Python eine Zeichenfolge (oder ein Tupel) x zuordne und dann die Zeichenfolge ändere, warum kümmert es mich dann, wenn es sich um das ursprüngliche Objekt handelt? Solange die Variable auf meine Daten verweist, ist das alles, was zählt.
>>> x='hello'
>>> id(x)
1234567
>>> x='good bye'
>>> id(x)
5432167
x
verweist immer noch auf die Daten, die ich möchte. Warum muss sich jemand darum kümmern, ob die ID gleich oder verschieden ist?
Antworten:
unveränderliche Objekte können eine wesentliche Optimierung ermöglichen; Dies ist vermutlich der Grund, warum Strings auch in Java unveränderlich sind, ganz separat entwickelt wurden, aber ungefähr zur gleichen Zeit wie Python, und fast alles ist in wirklich funktionierenden Sprachen unveränderlich.
Insbesondere in Python können nur unveränderliche Elemente hashbar sein (und daher Mitglieder von Mengen oder Schlüssel in Wörterbüchern). Auch dies ist eine Optimierung, aber weit mehr als nur "substanziell" (das Entwerfen anständiger Hash-Tabellen, in denen vollständig veränderbare Objekte gespeichert sind, ist ein Albtraum - entweder Sie erstellen Kopien von allem, sobald Sie es hashen, oder der Albtraum, zu überprüfen, ob der Hash des Objekts vorliegt hat sich geändert, seit Sie das letzte Mal darauf hingewiesen haben, dass es seinen hässlichen Kopf zeigt.
Beispiel für ein Optimierungsproblem:
quelle
random
Anrufen dominiert (versuchen Sie genau das, Sie werden sehen!), Also nicht sehr wichtig. Versuchen Sie espython -mtimeit -s "x=23" "[x,x]"
und Sie werden eine aussagekräftigere Beschleunigung von 2-3 Mal für das Erstellen des Tupels im Vergleich zum Erstellen der Liste sehen.Keine der obigen Antworten weist auf das eigentliche Problem von Tupeln gegen Listen hin, das viele Python-Neulinge nicht vollständig zu verstehen scheinen.
Tupel und Listen dienen unterschiedlichen Zwecken. Listen speichern homogene Daten. Sie können und sollten eine Liste wie diese haben:
Der Grund für die korrekte Verwendung von Listen liegt darin, dass dies alles homogene Datentypen sind, insbesondere die Namen von Personen. Aber nehmen Sie eine Liste wie diese:
Diese Liste enthält den vollständigen Namen einer Person und ihr Alter. Das ist keine Art von Daten. Die richtige Art, diese Informationen zu speichern, ist entweder in einem Tupel oder in einem Objekt. Nehmen wir an, wir haben einige:
Die Unveränderlichkeit und Veränderlichkeit von Tupeln und Listen ist nicht der Hauptunterschied. Eine Liste ist eine Liste derselben Art von Elementen: Dateien, Namen, Objekte. Tupel sind eine Gruppierung verschiedener Objekttypen. Sie haben unterschiedliche Verwendungszwecke und viele Python-Codierer missbrauchen Listen für das, wofür Tupel gedacht sind.
Bitte nicht.
Bearbeiten:
Ich denke, dieser Blog-Beitrag erklärt, warum ich das besser finde als ich: http://news.e-scribe.com/397
quelle
In diesem speziellen Fall gibt es wahrscheinlich keinen Punkt. Dies ist kein Problem, da dies nicht der Fall ist, in dem Sie die Verwendung eines Tupels in Betracht ziehen würden.
Wie Sie hervorheben, sind Tupel unveränderlich. Die Gründe für unveränderliche Typen gelten für Tupel:
Beachten Sie, dass eine bestimmte Python-Implementierung möglicherweise nicht alle oben genannten Funktionen nutzt.
Wörterbuchschlüssel müssen unveränderlich sein, andernfalls können durch Ändern der Eigenschaften eines Schlüsselobjekts Invarianten der zugrunde liegenden Datenstruktur ungültig werden. Tupel können daher möglicherweise als Schlüssel verwendet werden. Dies ist eine Folge der konstanten Korrektheit.
Siehe auch " Einführung in Tupel " von Dive Into Python .
quelle
==
Implementierung auf Plattformebene.(1,2,3) == (1,2,3)
. Das ist eher eine Frage des Praktikums.Manchmal verwenden wir gerne Objekte als Wörterbuchschlüssel
Für das, was es wert ist, sind in letzter Zeit Tupel (2.6+)
index()
undcount()
Methoden gewachsenquelle
Ich habe immer festgestellt, dass zwei völlig getrennte Typen für dieselbe grundlegende Datenstruktur (Arrays) ein umständliches Design sind, in der Praxis jedoch kein wirkliches Problem. (Jede Sprache hat ihre Warzen, einschließlich Python, aber dies ist keine wichtige.)
Das sind verschiedene Dinge. Die Veränderlichkeit hängt nicht mit dem Ort zusammen, an dem sie gespeichert ist. es bedeutet, dass sich das Zeug, auf das es zeigt, nicht ändern kann.
Python-Objekte können den Speicherort nicht ändern, nachdem sie erstellt wurden, veränderbar oder nicht. (Genauer gesagt kann sich der Wert von id () nicht ändern - in der Praxis auch.) Der interne Speicher von veränderlichen Objekten kann sich ändern, aber das ist ein verstecktes Implementierungsdetail.
Dadurch wird die Variable nicht geändert ("mutiert"). Es wird eine neue Variable mit demselben Namen erstellt und die alte verworfen. Vergleichen Sie mit einer Mutationsoperation:
Wie andere bereits betont haben, können auf diese Weise Arrays als Schlüssel für Wörterbücher und andere Datenstrukturen verwendet werden, die unveränderlich sein müssen.
Beachten Sie, dass Schlüssel für Wörterbücher nicht vollständig unveränderlich sein müssen. Nur der Teil, der als Schlüssel verwendet wird, muss unveränderlich sein. Für einige Anwendungen ist dies eine wichtige Unterscheidung. Sie könnten beispielsweise eine Klasse haben, die einen Benutzer darstellt, der Gleichheit und einen Hash mit dem eindeutigen Benutzernamen vergleicht. Sie können dann andere veränderbare Daten an die Klasse hängen - "Benutzer ist angemeldet" usw. Da dies weder die Gleichheit noch den Hash beeinflusst, ist es möglich und absolut gültig, diese als Schlüssel in einem Wörterbuch zu verwenden. Dies wird in Python nicht allzu häufig benötigt. Ich weise nur darauf hin, da mehrere Leute behauptet haben, dass Schlüssel "unveränderlich" sein müssen, was nur teilweise richtig ist. Ich habe dies jedoch oft mit C ++ - Karten und -Sätzen verwendet.
quelle
Wie Gnibbler in einem Kommentar anbot, hatte Guido eine Meinung , die nicht vollständig akzeptiert / geschätzt wird: „Listen sind für homogene Daten, Tupel sind für heterogene Daten“. Natürlich interpretierten viele der Gegner dies so, dass alle Elemente einer Liste vom gleichen Typ sein sollten.
Ich sehe es gerne anders, ähnlich wie andere es auch in der Vergangenheit getan haben:
Beachten Sie, dass ich alist als homogen betrachte, auch wenn type (alist [1])! = Type (alist [2]).
Wenn ich die Reihenfolge der Elemente ändern kann und keine Probleme in meinem Code haben (abgesehen von Annahmen, z. B. "es sollte sortiert werden"), sollte eine Liste verwendet werden. Wenn nicht (wie im
blue
obigen Tupel ), sollte ich ein Tupel verwenden.quelle
Sie sind wichtig, da sie dem Anrufer garantieren, dass das Objekt, das sie übergeben, nicht mutiert wird. Wenn du das tust:
Der Anrufer hat keine Garantie für den Wert von a nach dem Anruf. Jedoch,
Jetzt wissen Sie als Anrufer oder als Leser dieses Codes, dass a dasselbe ist. Sie könnten für dieses Szenario immer eine Kopie der Liste erstellen und diese übergeben, aber jetzt verschwenden Sie Zyklen, anstatt ein Sprachkonstrukt zu verwenden, das semantischer Sinn macht.
quelle
Sie können hier für eine Diskussion darüber sehen
quelle
Ihre Frage (und Ihre nachfolgenden Kommentare) konzentrieren sich darauf, ob sich die id () während einer Aufgabe ändert. Es ist vielleicht nicht der beste Ansatz, sich auf diesen Folgeeffekt des Unterschieds zwischen dem Ersetzen unveränderlicher Objekte und der Modifikation veränderlicher Objekte anstatt auf den Unterschied selbst zu konzentrieren.
Bevor wir fortfahren, stellen Sie sicher, dass das unten gezeigte Verhalten Ihren Erwartungen an Python entspricht.
In diesem Fall wurde der Inhalt von a2 geändert, obwohl nur a1 ein neuer Wert zugewiesen wurde. Im Gegensatz zu folgenden:
In diesem letzteren Fall haben wir die gesamte Liste ersetzt, anstatt ihren Inhalt zu aktualisieren. Bei unveränderlichen Typen wie Tupeln ist dies das einzige zulässige Verhalten.
Warum ist das wichtig? Angenommen, Sie haben ein Diktat:
Mit einem Tupel kann das Wörterbuch sicher sein, dass seine Schlüssel nicht "darunter" in Elemente geändert werden, die einen anderen Wert haben. Dies ist wichtig, um eine effiziente Implementierung zu ermöglichen.
quelle