Abschnitt 5 · Lektion 7
Tupel und der Kassenbon
Ein Posten auf dem Kassenbon besteht aus drei Werten. Was es ist, wie viele und was eins kostet. Die drei gehören zusammen, und getrennt ergeben sie wenig Sinn. Mit einer 2 allein kann niemand etwas anfangen.
Bisher standen solche Werte auf zwei Listen, Artikel hier, Preise da, und zip hat sie wieder
zusammengebracht. Das ging gut, solange beide gleich lang waren. Sicherer ist es, wenn sie gar nicht
erst auseinanderkommen.
Werte, die zusammengehören
posten = ("Brot", 2, 2.49)
print(posten)
print(posten[0], posten[-1])
print(len(posten))
posten[1] = 3 ("Brot", 2, 2.49) ist ein Tupel (tuple). Das sind mehrere Werte in runden Klammern, mit Kommas
getrennt. Lesen kannst du es wie eine Liste, über Positionen ab 0 oder von hinten mit -1, und
len() zählt die Teile. print zeigt es mit runden Klammern, damit man es von einer Liste
unterscheiden kann.
Gedacht ist es aber für etwas anderes. Eine Liste hält viele Dinge derselben Sorte, eine Woche Temperaturen oder einen Zettel voller Sachen, und es dürfen jederzeit mehr oder weniger werden. Ein Tupel hält die Teile eines einzigen Dings. Name, Menge und Preis eines Postens. Tag, Monat und Jahr eines Datums. Breite und Länge eines Ortes. Wie viele Teile es sind, steht fest, und jede Position hat ihre eigene Bedeutung. Position 1 ist immer die Menge.
Ein Tupel lässt sich nicht ändern
Der zweite Unterschied steht in der letzten Zeile im Beispiel oben. Ein Tupel kann man nicht ändern.
Wenn du die Menge nachträglich auf 3 setzen willst, bekommst du
TypeError: 'tuple' object does not support item assignment, also „ein Tupel erlaubt keine
Zuweisung an einen Eintrag“. append, remove und die anderen Methoden der Liste gibt es für Tupel
auch nicht.
Das klingt nach einem Nachteil. Meistens ist es ein Schutz. Ein Posten, der einmal auf dem Bon steht, soll sich nicht still ändern, nur weil irgendwo weiter unten im Programm jemand etwas überschreibt. Brauchst du einen anderen Posten, baust du einen neuen.
Auspacken
posten = ("Brot", 2, 2.49)
name, menge, preis = posten
print(f"{menge} x {name} kostet {menge * preis:.2f} Euro") Mit Positionen zu arbeiten wäre mühsam, denn posten[1] * posten[2] liest niemand gern. Deshalb
packt man ein Tupel aus (unpacking). name, menge, preis = posten verteilt die drei Teile der Reihe
nach auf drei Namen. Danach liest sich die Rechnung wie ein Satz, menge * preis.
posten = ("Brot", 2, 2.49)
name, preis = posten Links müssen genauso viele Namen stehen, wie das Tupel Teile hat. Sonst bricht Python ab, hier mit
ValueError: too many values to unpack (expected 2, got 3). Erwartet waren zwei, gekommen sind
drei. Ältere Versionen lassen das got 3 weg. Im umgekehrten Fall heißt es
not enough values to unpack, zu wenige Werte zum Auspacken.
Auspacken in der Schleife
einkauf = [("Brot", 2, 2.49), ("Milch", 1, 1.19), ("Kaffee", 1, 6.99)]
for name, menge, preis in einkauf:
print(f"{name}: {menge * preis:.2f}") Richtig nützlich wird das mit einer Liste aus Tupeln. Jeder Eintrag der Liste ist ein Posten, und
for name, menge, preis in einkauf: packt in jeder Runde den nächsten Posten gleich aus. So sieht
eine Tabelle in Python aus. Die Liste sind die Zeilen, und jedes Tupel ist eine Zeile mit ihren
Spalten. In Abschnitt 12 kommen solche Zeilen aus echten Tabellendateien.
for paar in enumerate(["Brot", "Milch"], start=1):
print(paar)
for paar in zip(["Brot", "Milch"], [2.49, 1.19]):
print(paar) Damit ist auch geklärt, was beim Durchlaufen der Listen noch offen war. enumerate und zip
liefern in jeder Runde ein Tupel, Nummer und Eintrag oder Artikel und Preis. Steht nach dem for
nur ein Name, landet das ganze Tupel darin, wie im Beispiel. Stehen dort zwei, wird es ausgepackt.
So war es bei for nummer, sache in enumerate(einkauf).
Das Komma macht das Tupel
preis = 2,5
print(preis)
print(type(preis))
print(preis * 3) In Lektion 1.3 hat print(2,5 * 2) zwei Zahlen ausgegeben statt einer Rechnung, weil das Komma dort
zwei Werte für print getrennt hat. Ohne print drumherum macht das Komma etwas anderes.
preis = 2,5 legt in preis ein Tupel aus der 2 und der 5 ab. Ein Tupel entsteht nämlich gar nicht
durch die runden Klammern, sondern durch das Komma. Die Klammern schreibt man trotzdem fast immer
hin, damit man es sieht.
Wenn du also einen Preis mit Komma eintippst, rechnest du ab dieser Zeile mit einem Tupel, und eine
Fehlermeldung gibt es dafür nicht. preis * 3 ergibt dann nicht 7,5, sondern (2, 5, 2, 5, 2, 5).
Das ist dasselbe Wiederholen wie bei Text mal Zahl. Steht so etwas in einer Ausgabe, wo ein Betrag
sein sollte, lohnt ein Blick auf die Kommas.
Was die Aufgabe will
Der Kassenbon aus Lektion 2.4 kommt wieder, diesmal aus einer Liste von Posten. Jeder Posten ist ein Tupel aus Name, Menge und Einzelpreis. Auf den Bon gehört in jeder Zeile der Preis für die ganze Menge, und darunter kommen eine Linie und die Summe, im selben Format wie damals.
Zum Mitnehmen
Ein Tupel bündelt die Teile eines Dings, beim Kassenbon also was ein Posten ist, wie viele und was einer kostet. Geschrieben wird es in runden Klammern, und ändern lässt es sich nicht. Beim Auspacken bekommt jeder Teil einen eigenen Namen.
Jetzt du
Basis Konto, kostenlosZu dieser Lektion gehört eine Aufgabe. Du schreibst den Code selbst, und nach jedem Lauf sagt dir eine Prüfliste, was schon stimmt.
Dafür brauchst du das Basis Konto. Es kostet nichts, und ein Passwort gibt es auch nicht.
In diesem Kurs läuft dein Code auf einem Server. Dafür hat das Basis Konto 1 Stunde im Monat, mehr Zeit gibt es mit dem Premium Konto.
Was in dieser Lektion steckt
-
Artikel mit 6 Beispielen zum Ausprobieren
Steht hier, ohne Konto lesbar.
-
Aufgabe, dein Code läuft auf einem Server
Öffnet sich mit dem Basis Konto.