Tupel gleichen Listen – es lassen sich mehrere Elemente auch unterschiedlichen Datentyps in einer Variable zusammenfassen. Tupel wie Listen lassen sich beliebig schachteln. Der große Unterschied ist, dass, einmal zugewiesen, sich die Elemente eines Tupels nicht mehr ändern lassen. Im folgenden schauen wir uns genauer an, wann es sinnvoll ist, Tupel zu verwenden und wie diese angelegt werden.
Challenge
Schreibe eine Funktion, die als Parameter einen String erhält und den String selbst sowie die Länge der Zeichenkette zurückgibt.
Gut zu wissen…
Ein Tupel wird mit runden Klammern (bei Listen sind es eckige Klammern) angelegt. Die runden Klammern können auch weggelassen werden. Tupel machen das Leben oft einfacher. Man kann nämlich mit Hilfe eines Tupels mehrere (unterschiedliche) Variablen auf einmal zuweisen. Umgekehrt lassen sich die Variablen innerhalb eines Tupels wieder entpacken, d.h. sie lassen sich einzelnen Variablen zuweisen. Ist ein Tupel einmal angelegt, lassen sich die Elemente innerhalb eines Tupels nicht mehr ändern.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
# Leerer Tupel >>> ein_tupel = () >>> ein_tupel () # Tupel mit verschiedenen Datentypen >>> ein_tupel_1 = (5, "Hallo Welt", 0.7) >>> ein_tupel (5, 'Hallo Welt', 0.7) # Tupel ohne Klammern >>> ein_tupel_2 = 5, "Hallo Welt", 7.2 >>> ein_tupel_2 5, 'Hallo Welt', 7.2 # Auspacken eines Tupels geht auch... >>> x, y, z = ein_tupel_2 >>> print(x) 5 >>> print(y) Hallo Welt >>> print(z) 7,2 |
Interessant wird es noch bei Anlage eines Tupels mit einem Element. Hier reicht es nicht, das Element in Klammern zu setzen. Python würde sonst den Datentypen des einzelnen Elements zuweisen, z.B. String oder Integer. Deshalb muss für ein Tupel mit einem Element nach der Angabe des Elements ein Komma folgen:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
# Leider kein Tupel... >>> mein_str_Tupel = ("Hallo Welt") >>> type(mein_str_Tupel) <class 'str'> # ... das ist ein Tupel >>> mein_Tupel = ("hallo",) >>> type(mein_Tupel) <class 'tuple'> # oder so: >>> mein_Tupel = "hallo", >>> type(mein_Tupel) <class 'tuple'> |
Der Zugriff auf Tupel erfolgt mit denselben Operatoren und Funktionen wie bei Listen. Nur bei der Änderung von Tupeln gibt es Unterschiede: Da Tupel unveränderbar sind (immutable), gibt es keine Methoden zum Hinzufügen oder Wegnahme einzelner Elemente wie beispielsweise append()
oder remove()
. Auch können einzelne Elemente nicht durch Zuweisen eines neuen Elements geändert werden. Sollten allerdings Elemente enthalten sein, die vom Datentyp List oder Dictionary sind, dann lassen sich die Elemente dieser Elemente ändern.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
>>> mein_tupel = (1, 7, [3, 4], 5) >>> mein_tupel[1] = 2 TypeError: 'tuple' object does not support item assignment # Ein Eintrag mit einem modifizierbaren Sequenztypen kann geändert werden: >>> mein_tupel[2][0] = 10 >>> mein_tupel (1, 7, [10, 4], 5]) # Tupel lassen sich überschreiben, indem der Tupelvariablen komplett neue # Werte zugeordnet werden >>> mein_tupel = ("Einstein", "Fragezeichen") >>> mein_tupel = ("Hallo", "Welt") >>> mein_Tupel Hallo Welt |
Die Unveränderlichkeit von Tupeln bedeutet auch, dass einzelne Elemente nicht gelöscht werden können. Nur ein kompletter Tupel lässt sich mit Hilfe des Schlüsselwortes del löschen.
1 2 3 4 5 6 7 8 |
>>> mein_tuple = ("Hallo", "Welt") # einzelne Einträge lassen sich nicht löschen >>> del mein_tupel[1] TypeError: 'tuple' object doesn't support item deletion # der gesamte Tupel kann gelöscht werden >>> del mein_tupel |
Nutzung von Tupeln
Um zu entscheiden, wann Tupel (und wann Listen) verwendet werden sollten, hilft es, sich den Hauptunterschied noch einmal bewusst zu machen: Tupel sind unveränderbar, sie haben also eine feste Größe. Listen dagegen sind veränderbar. Wird ein Element in der Liste geändert, bleibt die Speicheradresse dieselbe. Werte werden im Speicher entsprechend geändert.
Tupel benötigen weniger Speicherplatz als Listen, u.a. weil sie weniger Speicher Overhead im Vergleich zu Listen haben. Deswegen ist (bei sehr großen Datenmengen) die Suche von Elementen oder das Iterieren über Elemente bei Tupeln etwas schneller (mehr Information zur Performanz gibt es z.B. in Micha Gorelick, Ian Ozsvald, High Performance Python).
1 2 3 4 5 6 |
>>> tuple_einkauf = ('Bananen', 'Eier', 'Putengulasch', 'Ketchup') >>> list_einkauf = ['Bananen', 'Eier', 'Putengulasch', 'Ketchup'] >>> tuple_names.__sizeof__() 56 >>> list_names.__sizeof__() 72 |
Manche Werte sollen sich innerhalb eines Programmablaufes nicht ändern (Konstanten). Um zu verhindern, dass fälschlicherweise Änderungen gemacht werden, bietet es sich an, dass diese in einer unveränderbaren Variable abspeichert werden.
Oft werden Tupel als Rückgabewerte bei Funktionen genutzt, um die verschiedenen Werte in Variablen des Hauptprogramms zu “entpacken” (unpacking).
1 2 3 4 5 6 7 |
def beispiel_rueckgabe(zahl): zahl1 = zahl * 2 zahl2 = zahl * 3 return (zahl1, zahl2) # oder: return zahl1, zahl2 x, y = beispiel_rueckgabe(3) print(x,y) # Ausgabe: 6,9 |
Dictionaries (haben wir an dieser Stelle noch nicht kennen gelernt) bestehen aus Schlüssel-Wert Paaren. Die Schlüssel eines Dictionaries müssen einen unveränderbaren Datentypen aufweisen (die ein Hashing der Schlüssel möglich machen). Deshalb lassen sich hierfür Tupel, aber keine Listen verwenden.
1 2 3 4 5 |
>>> key_tupel= {('Brosnahan','Rachel'):'The Marvelous Mrs. Maisel'} >>> key_tupel {('Brosnahan', 'Rachel'): 'The Marvelous Mrs. Maisel'} >>> key_list = {['Brosnahan','Rachel']:'The Marvelous Mrs. Maisel'} TypeError: unhashable type: 'list' |
Spickzettel…
