Tupel und Entpacken
Eine Liste, die sich nicht verändern lässt, wenn genau das gewünscht ist, Entpacken, damit du Namen statt Indizes benutzt, Tauschen in einer Zeile und die Falle mit (5) gegenüber (5,).
Wie möchtest du lernen?
Das Problem, das wir lösen
Drei Tage Wetter müssen notiert werden — für jeden Tag der Name, die Temperatur und die Luftfeuchtigkeit.
Eine Liste erledigt die Aufgabe: ["monday", 31.5, 78]. Es funktioniert, und zwei Dinge stören dabei.
Erstens: Diese Liste kann verändert werden. Wenn versehentlich per append an Montags Datensatz etwas angehängt wird, sagt Python kein Wort — obwohl in einem Datensatz nie vier Dinge sein sollen. Etwas, das sich nicht verändern darf, in einen Behälter zu legen, der sich verändern lässt, ist ein stilles Risiko.
Zweitens: Die drei Werte wieder herauszuholen bedeutet, record[0], record[1], record[2] zu schreiben — nach Nummer, nicht nach Namen. Sechs Monate später wird niemand, der record[1] liest, wissen, ob das die Temperatur oder die Luftfeuchtigkeit ist.
Ein Tupel beantwortet beides: Es ist eine Liste, die sich nicht verändern lässt — und es bringt eine Fähigkeit namens Entpacken, mit der du Namen statt Indizes benutzen kannst.
Am Ende dieses Kapitels kannst du
- Ein Tupel bauen und sagen, wann ein Tupel richtig ist und eine Liste nicht
- Mit Entpacken mehrere Werte auf einmal in mehrere Namen legen
- Zwei Variablen in einer einzigen Zeile tauschen
(5)von(5,)unterscheiden- Erklären, warum
appendan einem Tupel einenAttributeErrorwirft
Voraussetzungen: Listen sortieren, und die Methoden, die dazugehören.
Ein Tupel — eine Liste, die sich nicht verändern lässt
Runde Klammern statt eckiger:
point = (3, 7)
print(point)
print(point[0])
print(len(point))(3, 7)
3
2Lesen, Indizieren, len, Slices, in, Iterieren mit for — alles, was du mit einer Liste getan hast, funktioniert. Es gibt einen Unterschied, und er ist das Ganze:
point = (3, 7)
point[0] = 5TypeError: 'tuple' object does not support item assignmentKommt dir diese Meldung bekannt vor? Sie ist Wort für Wort dieselbe, die Kapitel sechs ausgab, als ein Zeichen in einem String verändert wurde — mit 'str' statt 'tuple'. Pythons unveränderliche Dinge beschweren sich alle in derselben Sprache.
Auch die Methoden, die Dinge verändern, fehlen:
point = (3, 7)
point.append(9)AttributeError: 'tuple' object has no attribute 'append'Ein AttributeError bedeutet „dieses Objekt hat nichts, was diesen Namen trägt“. Ein Tupel kann nicht verändert werden, also hat ein Tupel überhaupt keine Methode namens append. Python stoppt schon beim Nachschlagen von point.append, bevor es auch nur versucht, 9 hinzuzufügen. Vergleiche es mit dem vorherigen Beispiel: point[0] = 5 hat eine Operation verlangt, die ein Tupel nicht erlaubt, also war das ein TypeError; hier existiert die Methode selbst nicht, also ist es ein AttributeError.
Warum das ein Vorteil ist und keine Einschränkung
Zunächst sieht ein Tupel aus wie eine Liste, der Features fehlen. Dreh die Sache um: Wenn sich etwas nicht verändern soll, verhindert das Ablegen an einem Ort, an dem es sich nicht verändern kann, den Fehler, bevor er passiert.
Es macht keinen Sinn, eine dritte Zahl zu den Koordinaten (3, 7) hinzuzufügen. Ein Datum (2026, 9, 16) hat keinen vierten Teil. Wenn sie in einem Tupel stecken, kommen diese Unfälle sofort als Fehler an und nicht als Bugs erst später.
Als Regel: Eine feste Anzahl von Dingen, von denen jedes etwas anderes bedeutet — Tupel. Eine unbekannte Anzahl von Dingen, alle von derselben Art — Liste.
Drei Tage Wetter sind also Tupel in einer Liste: Die Anzahl der Tage ist nicht bekannt (eine Liste), aber jeder Datensatz enthält genau drei Dinge (ein Tupel).
Entpacken — wo der eigentliche Vorteil liegt
point = (3, 7)
x, y = point
print(x)
print(y)3
7Zwei Namen und zwei Werte in einer Zeile. Und jetzt ist es y statt point[1] — ein Name, der sich beim Lesen selbst erklärt.
Links müssen genauso viele Namen stehen wie rechts Werte da sind:
point = (3, 7)
x, y, z = pointValueError: not enough values to unpack (expected 3, got 2)Diese Meldung ist ungewöhnlich hilfreich — sie sagt dir, wie viele erwartet wurden und wie viele angekommen sind.
Entpacken beschränkt sich nicht auf Tupel; es funktioniert auch mit Listen. Am nützlichsten ist es bei Tupeln, weil dort die Anzahl der Werte im Voraus bekannt ist.
Tauschen, in einer Zeile
Andere Sprachen brauchen eine temporäre dritte Variable, um zwei Werte zu tauschen. Python nicht:
a = 1
b = 2
a, b = b, a
print(a, b)2 1Es lohnt sich zu verstehen, wie die Zeile funktioniert: Python wertet zuerst die gesamte rechte Seite aus und baut daraus ein Tupel (2, 1), und dann entpackt es das in die linke Seite. Obwohl sich also a ändert, ist der alte Wert von b bereits in diesem Tupel gefangen, und nichts geht verloren.
Die Klammern sind eigentlich nicht nötig
point = 3, 7
print(point)
print(type(point))(3, 7)
<class 'tuple'>Was ein Tupel ausmacht, ist das Komma, nicht die Klammern. Die Klammern sind für die Lesbarkeit da. Wenn du das weißt, sieht a, b = b, a nicht mehr nach Magie aus — b, a rechts ist einfach ein Tupel.
Und daraus entsteht eine Falle:
one = (5)
really = (5,)
print(type(one))
print(type(really))
print(len(really))<class 'int'>
<class 'tuple'>
1(5) ist kein Tupel — es ist eine Zahl in Klammern, genau wie (2 + 3). Ein Tupel mit einem Wert zu bauen, verlangt das Komma: (5,). Es sieht aus wie ein Tippfehler, und dieses Komma ist der ganze Unterschied.
Tupel in einer Schleife
people = [("rafi", 22), ("ahmed", 35)]
for name, age in people:
print(f"{name} is {age}")rafi is 22
ahmed is 35for name, age in people entpackt jedes Tupel direkt in zwei Namen. Kein person[0] und kein person[1] — und der Code sagt beim Lesen, was er meint.
Du hast das schon benutzt, ohne es zu wissen:
stock = ["pen", "bag"]
for pair in enumerate(stock):
print(pair)(0, 'pen')
(1, 'bag')enumerate liefert Tupel zurück. for position, item in enumerate(...) in Kapitel zwölf zu schreiben, hieß, sie zu entpacken — wir hatten einfach noch keinen Namen dafür.
Umwandeln zwischen beiden
as_list = [3, 7]
as_tuple = (3, 7)
as_list.append(9)
print(as_list)
print(as_tuple)
print(list(as_tuple))
print(tuple(as_list))[3, 7, 9]
(3, 7)
[3, 7]
(3, 7, 9)list() und tuple() bauen das eine aus dem anderen — jedes Mal etwas Neues, das Original bleibt unangetastet. So „veränderst“ du ein Tupel: baue eine Liste, ändere sie, baue wieder ein Tupel.
Ein vollständiges Beispiel
weather.py:
# A tuple is the right shape for a record that must not change
readings = [
("monday", 31.5, 78),
("tuesday", 33.0, 71),
("wednesday", 29.5, 85),
]
print("Day Temp Humidity")
for day, temp, humidity in readings:
print(f"{day:<10} {temp:>5} {humidity:>5}")
hottest = readings[0]
for reading in readings:
if reading[1] > hottest[1]:
hottest = reading
day, temp, humidity = hottest
print()
print(f"Hottest was {day} at {temp}")
temps = []
for _, temp, _ in readings:
temps.append(temp)
print("Temps :", temps)
print("Average :", round(sum(temps) / len(temps), 2))Day Temp Humidity
monday 31.5 78
tuesday 33.0 71
wednesday 29.5 85
Hottest was tuesday at 33.0
Temps : [31.5, 33.0, 29.5]
Average : 31.33Vier Dinge, die dir auffallen sollten.
Außen eine Liste, innen Tupel. Die Anzahl der Tage kann wachsen, also ist das Äußere eine Liste. Jeder Datensatz enthält genau drei Dinge, also sind die Inneren Tupel. So sehen echte Daten am häufigsten aus.
f"{day:<10}" und f"{temp:>5}" halten die Spalten gerade. < richtet nach links aus, > nach rechts, und die Zahl sagt, wie viel Breite belegt wird. Wie :.2f aus Kapitel sechs ist alles nach dem Doppelpunkt Formatierung.
Den heißesten Tag zu finden brauchte reading[1], weil beim Vergleich das ganze Tupel in der Hand liegt und nicht eines, das schon entpackt ist. Es wird entpackt, sobald es gefunden ist — deshalb hat die Zeile danach keine Indizes mehr.
for _, temp, _ in readings — der Unterstrich ist eine Konvention und bedeutet „den brauche ich nicht“. Für Python ist es ein ganz normaler Name; für Lesende sagt es, welche Teile absichtlich weggeworfen werden.
Wenn etwas schiefgeht
TypeError: 'tuple' object does not support item assignment Ein Versuch, einen Wert in einem Tupel zu verändern. Tupel können nicht verändert werden — nimm von Anfang an eine Liste, oder konvertiere mit list(...), ändere sie und konvertiere zurück.
AttributeError: 'tuple' object has no attribute 'append' Dieselbe Ursache in anderer Kleidung. Keine verändernde Methode — append, remove, sort — existiert an einem Tupel. sorted(my_tuple) funktioniert dagegen, weil es eine neue Liste zurückgibt und das Tupel unangetastet lässt.
ValueError: not enough values to unpack (expected 3, got 2) Links stehen mehr Namen als rechts Werte. print(len(record)) zeigt, wie viele wirklich darin sind.
ValueError: too many values to unpack (expected 2) Das Gegenteil — mehr Werte als Namen.
Ich habe ein Tupel mit einem Wert gebaut, und es ist kein Tupel Das Komma fehlt. (5) ist eine Zahl; (5,) ist ein Tupel.
Eine Liste in meinem Tupel hat sich verändert Ein Tupel schützt seine eigene Struktur — welche Dinge darin sind, kann sich nicht ändern. Aber wenn eines dieser Dinge selbst veränderbar ist, etwa eine Liste, kann sich das Innere dieser Liste trotzdem ändern. In ([1, 2], 3) kannst du an der ersten Liste append aufrufen.
Schritt 4 von 6 — Vorhersagen
Prüfe dein Verständnis
Was wird nach dem Entpacken ausgegeben?
point = (3, 7)
x, y = point
print(y, x)- A3 7
- B(3, 7)
- CEin `ValueError`
- D7 3
Ein Versuch, an ein Tupel append aufzurufen. Welcher Fehler kommt, und warum gerade dieser?
point = (3, 7)
point.append(9)- AEin `ValueError`
- BNichts passiert; das Tupel bleibt unverändert
- CEin `AttributeError` — ein Tupel kann sich nicht verändern, also existieren die verändernden Methoden darauf schlicht nicht
- DEin `TypeError` — `append` ist an einem Tupel nicht erlaubt
Die beiden Zeilen unterscheiden sich um ein Komma. Was meldet type()?
one = (5)
really = (5,)
print(type(one))
print(type(really))- A<class 'int'> <class 'int'>
- B<class 'tuple'> <class 'tuple'>
- C<class 'int'> <class 'tuple'>
- D<class 'tuple'> <class 'int'>
Zum Antworten brauchst du ein Konto
Melde dich an, um deine Antworten zu prüfen
Die Fragen stehen oben, und sie im Kopf durchzuarbeiten ist der wichtige Teil. Melde dich an, um die Antworten, die Erklärungen und die dreistufigen Hinweise zu sehen.
Jetzt bist du dran
Schreib eine Datei namens contacts.py, die eine Liste von mindestens fünf Leuten enthält — jede Person ein Tupel aus Name, Alter und Lieblingsfach.
Dann:
- Gib alle in ausgerichteten Spalten aus, mit
for name, age, subject in contacts: - Finde die älteste Person, entpacke sie und gib einen Satz über sie aus
- Baue eine Liste nur mit den Namen und gib sie in einer Zeile mit
joinaus - Gib das Durchschnittsalter aus
- Tausche zwei Variablen in einer einzigen Zeile und zeige, dass es funktioniert hat
Dann brich es dreimal absichtlich, und lies jede Meldung:
- Versuch, das Alter in einem der Tupel zu verändern
- Versuch, an ein Tupel
appendaufzurufen - Versuch, ein Tupel mit drei Werten in zwei Namen zu entpacken
Drei verschiedene Fehler kommen zurück — TypeError, AttributeError, ValueError. Wenn du dir selbst erklären kannst, welcher welcher ist und warum, gehören dir die Tupel.
Schritt 6 von 6
Herausforderung — das Kapitel-Quiz
Zehn Fragen von leicht bis schwer. Die letzten sind absichtlich knifflig.
Melde dich an, um das Quiz zu machen