Ich bin neu in Python, daher könnte diese Frage ein wenig grundlegend sein. Ich habe ein Tupel namens values
, das Folgendes enthält:
('275', '54000', '0.0', '5000.0', '0.0')
Ich möchte den ersten Wert (dh 275
) in diesem Tupel ändern, aber ich verstehe, dass Tupel unveränderlich sind und daher values[0] = 200
nicht funktionieren. Wie kann ich das erreichen?
Antworten:
Zuerst müssen Sie fragen, warum Sie dies tun möchten.
Aber es ist möglich über:
Aber wenn Sie etwas ändern müssen, ist es wahrscheinlich besser, es als zu behalten
list
quelle
Abhängig von Ihrem Problem kann das Schneiden eine wirklich gute Lösung sein:
Auf diese Weise können Sie mehrere Elemente hinzufügen oder auch einige Elemente ersetzen (insbesondere wenn es sich um "Nachbarn" handelt. Im obigen Fall ist das Casting in eine Liste wahrscheinlich geeigneter und lesbarer (obwohl die Slicing-Notation viel kürzer ist).
quelle
Nun, wie Trufa bereits gezeigt hat, gibt es grundsätzlich zwei Möglichkeiten, das Element eines Tupels bei einem bestimmten Index zu ersetzen. Konvertieren Sie entweder das Tupel in eine Liste, ersetzen Sie das Element und konvertieren Sie es zurück oder erstellen Sie ein neues Tupel durch Verkettung.
Also, welche Methode ist besser, das heißt schneller?
Es stellt sich heraus, dass bei kurzen Tupeln (unter Python 3.3) die Verkettung tatsächlich schneller ist!
Wenn wir uns jedoch längere Tupel ansehen, ist die Listenkonvertierung der richtige Weg:
Bei sehr langen Tupeln ist die Listenkonvertierung wesentlich besser!
Die Leistung der Verkettungsmethode hängt auch von dem Index ab, bei dem wir das Element ersetzen. Für die Listenmethode ist der Index irrelevant.
Also: Wenn Ihr Tupel kurz ist, schneiden Sie es auf und verketten Sie es. Wenn es lang ist, führen Sie die Listenkonvertierung durch!
quelle
Es ist mit einem Einzeiler möglich:
quelle
values
?i = 2; values = (*values[:i], '300', *values[i+1:])
Nicht, dass dies überlegen wäre, aber wenn jemand neugierig ist, kann dies in einer Zeile erfolgen mit:
quelle
tuple = tuple(200 if i == 0 else _ for i, _ in enumerate(tuple))
? (Warum nicht Generator Verständnis?)Ich glaube, dies beantwortet die Frage technisch, aber mache das nicht zu Hause. Im Moment beinhalten alle Antworten das Erstellen eines neuen Tupels, aber Sie können
ctypes
ein Tupel im Speicher ändern. Unter Verwendung verschiedener Implementierungsdetails von CPython auf einem 64-Bit-System können Sie dies folgendermaßen tun:quelle
Wie Hunter McMillen in den Kommentaren schrieb, sind Tupel unveränderlich. Sie müssen ein neues Tupel erstellen, um dies zu erreichen. Zum Beispiel:
quelle
EDIT: Dies funktioniert noch nicht bei Tupeln mit doppelten Einträgen !!
Basierend auf Pooyas Idee :
Wenn Sie dies häufig vorhaben (was Sie nicht tun sollten, da Tupel aus einem bestimmten Grund unveränderlich sind), sollten Sie Folgendes tun:
Oder basierend auf Jons Idee :
quelle
Frist, fragen Sie sich, warum Sie Ihre mutieren wollen
tuple
. Es gibt einen Grund, warum Strings und Tupel in Ptyhon unveränderlich sind . Wenn Sie Ihre mutieren möchten,tuple
sollte es wahrscheinlich eine seinlist
.Zweitens, wenn Sie Ihr Tupel immer noch mutieren möchten, können Sie es
tuple
in einlist
konvertieren und dann zurückkonvertieren und das neue Tupel derselben Variablen neu zuweisen. Dies ist großartig, wenn Sie Ihr Tupel nur einmal mutieren . Ansonsten halte ich das persönlich für nicht intuitiv. Da im Wesentlichen ein neues Tupel erstellt wird und jedes Mal, wenn Sie das Tupel mutieren möchten, müssen Sie die Konvertierung durchführen. Auch wenn Sie den Code lesen, wäre es verwirrend zu überlegen, warum nicht einfach eine erstellenlist
? Aber es ist schön, weil es keine Bibliothek benötigt.Ich schlage vor,
mutabletuple(typename, field_names, default=MtNoDefault)
von mutabletuple 0.2 zu verwenden . Ich persönlich halte diesen Weg für intuitiver und lesbarer. Das persönliche Lesen des Codes würde wissen, dass der Autor beabsichtigt, dieses Tupel in Zukunft zu mutieren. Der Nachteil im Vergleich zurlist
obigen Konvertierungsmethode besteht darin, dass Sie hierfür eine zusätzliche py-Datei importieren müssen.TL; DR : Versuchen Sie nicht zu mutieren
tuple
. Wenn Sie dies tun und es sich um eine einmalige Operation handelt, konvertieren Sie sietuple
in eine Liste, mutieren Sie sie, verwandeln Sie sielist
in eine neuetuple
und weisen Sie sie wieder der alten Variablen zutuple
. Wenn Wünschetuple
und irgendwie vermeidenlist
und mehr als einmal mutieren wollen, dann erstellenmutabletuple
.quelle
basierend auf Jons Idee und der lieben Trufa
Es ändert alle Ihre alten Wertevorkommen
quelle
Das kannst du nicht. Wenn Sie es ändern möchten, müssen Sie eine Liste anstelle eines Tupels verwenden.
Beachten Sie, dass Sie stattdessen ein neues Tupel erstellen können, dessen erstes Element der neue Wert ist.
quelle
Ich habe festgestellt, dass der beste Weg zum Bearbeiten von Tupeln darin besteht, das Tupel mit der vorherigen Version als Basis neu zu erstellen.
Hier ist ein Beispiel, das ich verwendet habe, um eine hellere Version einer Farbe zu erstellen (ich hatte sie zu diesem Zeitpunkt bereits geöffnet):
Was es tut, ist, dass es die Tupelfarbe durchläuft und jedes Element liest, etwas damit macht und es schließlich dem neuen Tupel hinzufügt.
Also, was Sie wollen, wäre so etwas wie:
Das spezielle funktioniert nicht, aber das Konzept ist genau das, was Sie brauchen.
Das ist das Konzept.
quelle
Ich bin zu spät zum Spiel, aber ich denke, der einfachste , ressourcenschonendste und schnellste Weg (je nach Situation) besteht darin, das Tupel selbst zu überschreiben. Da dies die Notwendigkeit für die Erstellung von Listen und Variablen beseitigen würde und in einer Zeile archiviert wird.
Aber: Dies ist nur für eher kleine Tupel praktisch und beschränkt Sie auch auf einen festen Tupelwert. Dies ist jedoch ohnehin die meiste Zeit bei Tupeln der Fall.
In diesem speziellen Fall würde es also so aussehen:
quelle
tldr; Die "Problemumgehung" erstellt ein neues Tupelobjekt, ohne das Original zu ändern
Während dies eine sehr alte Frage ist, erzählte mir jemand von diesem Python-mutierenden Tupel-Wahnsinn. Was mich sehr überrascht / fasziniert hat und ein bisschen gegoogelt hat, bin ich hier gelandet (und andere ähnliche Beispiele online)
Ich habe einen Test durchgeführt, um meine Theorie zu beweisen
Hinweis
==
bewirkt Gleichheit undis
referenzielle Gleichheit (ist obj a dieselbe Instanz wie obj b)Ausbeuten:
quelle
Sie können keine Elemente in Tupeln ändern, aber Sie können die Eigenschaften veränderbarer Objekte in Tupeln ändern (z. B. wenn diese Objekte Listen oder tatsächliche Klassenobjekte sind).
Beispielsweise
quelle
ich war das:
und um sich zu ändern, tu es einfach
und du kannst ein Tupel ändern: D.
Hier wird es genau aus IDLE kopiert
quelle
x = (y)
tut nichts anderes, als x y zuzuweisen.Sie können den Wert des Tupels mithilfe der Referenzkopie ändern
quelle