3.1. Zusammengesetzte Datentypen#

Zusammengesetzte Datentypen sind strukturierte Sammlungen von Objekten. In Python sind vier solcher “zusammengesetzter Datentypen” vordefiniert: Tupel, Listen, Sets und Dictionaries. Tupel und Listen sind zugleich sequentielle Datentypen. Manche der Operationen und Operatoren, die wir schon im Zusammenhang mit Strings kennengelernt haben, können deswegen auch auf Tupel und Listen angewandt werden.

3.1.1. Tupel#

Tupel sind eine geordnete Abfolge von Elementen verschiedenen Datentyps. Das heißt, sie sind genau wie Strings ein sequentieller Datentyp. Tupel sind außerdem unveränderbar, genau wie Strings. Sie werden zum Beispiel verwendet, um unkompliziert die Werte zweier Variablen zu tauschen (siehe Beispiel unten). Im Kapitel zu Funktionen werden wir Tupeln auch noch einmal begegnen.

Beispiel

Fig. 3.1 Beispielobjekt vom Typ Tupel#

# Leeres Tupel erstellen
tpl = ()
print(tpl)
()
# Tupel mit einem Element: Komma nicht vergessen!
tpl = (1,)
print(tpl)
(1,)
# Tupel mit drei Elementen erstellen
tpl = ("a", 4, 5)
print(tpl)
('a', 4, 5)
# Auf Element mit dem Index 0 zugreifen
tpl[0]
'a'
# Tupel verketten
(3, 1) + ("Hallo", 5.0)
(3, 1, 'Hallo', 5.0)
tpl[0:1]
('a',)
tpl[1:3]
(4, 5)
# Länge
len(tpl)
3
# Wie oft kommt das Element 4 im Tupel tpl vor?
tpl.count(4)
1
# Werte zweier Variablen austauschen
x = 4
y = 5
# So geht es nicht:
# x = y
# y = x
# Variante 1: Kompliziert
temp = x
x = y
y = temp
# Variante 2: Unkompliziert
(x, y) = (y, x)
# Tupel kann man nicht veränern
# tpl[1] = 10

3.1.2. Listen#

Geordnete Abfolge von Elementen, die gewöhnlich denselben Datentyp haben, aber theoretisch verschiedene Datentypen haben könnten. Listen sind veränderbar, das heißt, dass Listenelemente ausgetauscht werden können.

Beispiel

Fig. 3.2 Beispielobjekt vom Typ Liste#

Liste aller Methoden, die für Objekte vom Typ Liste definiert sind: https://docs.python.org/3/tutorial/datastructures.html#more-on-lists.

# Leere Liste erstellen
lst = []
print(lst)
[]
# Liste mit vier Elementen desselben Datentyps erstellen
lst = [1, 3, 8, 3]
print(lst)
[1, 3, 8, 3]
# Liste mit drei Elementen verschiedener Datentypen erstellen
lst = ["a", 3, 5, True]
print(lst)
['a', 3, 5, True]
# Listen können auch selbst Listen enthalten: solche Listen heißen dann "verschachtelte Liste" oder "nested list" auf Englisch.
nested_lst = [[1, 2], [8, 3]]
print(nested_lst)
[[1, 2], [8, 3]]
# Länge
len(nested_lst)
2
# Auf Element mit dem Index 1 zugreifen
nested_lst[1]
[8, 3]
# Auf das erste Element der zweiten Liste in der verschachtelten Liste lst_3 zugreifen
nested_lst[1][0]
8
# Element verrechnen: hier nehmen wir wieder die einfache Liste
lst[2] + 1
6
# Element austauschen
lst[1] = 23
print(lst)
['a', 23, 5, True]
# Element am Ende der Liste hinzufügen
lst.append(50)
print(lst)
['a', 23, 5, True, 50]
# Zwei Listen kombinieren: Alternative 1
# liste_1 und liste_2 werden nicht verändert
liste_1 = [1, 4, 3]
liste_2 = [6, 8, 1]
liste_3 = liste_1 + liste_2
print(liste_3)
[1, 4, 3, 6, 8, 1]
# Zwei Listen kombinieren: Alternative 2
# liste_1 wird verändert
liste_1.extend(liste_2)
print(liste_1)
[1, 4, 3, 6, 8, 1]
# Letztes Element ausgeben und entfernen
liste_1.pop()
1
# Bestimmtes Element entfernen: Hier ist die Zahl nicht der Index sondern der Wert
liste_1.remove(4)
print(liste_1)
[1, 3, 6, 8]
# Wie oft kommt das Element 8 in der Liste liste_1 vor?
liste_1.count(8)
1
# Listen, deren Elemente Strings sind, kann man auch in einen String umwandeln:
str_liste = ["a", "b", "c"]
"".join(str_liste)
'abc'
# String in Liste umwandeln
dateiname = "kafka_strafkolonie_1919"
dateiname.split("_")
['kafka', 'strafkolonie', '1919']
# Um Objekte mit anderen Datentypen in eine Liste umzuwandeln, kann man auch die Funktion list() verwenden
# list() konvertiert Strings zeichenweise:
list("Rose")
['R', 'o', 's', 'e']
# Neue sortierte Liste erstellen: liste_1 wird dabei nicht verändert
liste_sortiert = sorted(liste_1)
print(liste_sortiert)
[1, 3, 6, 8]
# Liste sortieren: liste_1 wird dabei verändert
liste_1.sort()
print(liste_1)
[1, 3, 6, 8]
# Reihenfolge der Elemente umkehren
liste_1.reverse()
print(liste_1)
[8, 6, 3, 1]
# Alias erstellen: Also ein zweiter Name für dasselbe Objekt
kalt = [0, 4, 1, 9]
kuehl = kalt
kuehl.append(7)
print(kalt)
[0, 4, 1, 9, 7]
# Liste klonen
warm = [20, 31, 25, 28]
heiss = warm[:]
heiss.append(32)
print(warm)
[20, 31, 25, 28]

Beim Klonen wird ein neues Objekt erstellt; ein Alias ist dagegen nur ein weiterer Name, der auf dasselbe Objekt zeigt. Um den Unterschied zwischen den beiden Operationen besser nachzuvollziehen, könnt ihr den Code auf https://pythontutor.com/python-debugger.html#mode=edit eingeben und ausführen. Die Seite visualisiert, was in jeder Codezeile passiert.

3.1.3. Zusammenfassung: Operationen auf sequentiellen Datentypen#

Die folgende Tabelle ist der offiziellen Dokumentation zu Python 3.11.3 entnommen und gibt einen Überblick über die Operationen, die auf die drei sequentiellen Datentypen Strings, Tupel und Listen angewendet werden können. s steht für irgendein Objekt mit einem sequentiellen Datentyp.

Operator

Bedeutung

x in s

True, wenn ein Element in s gleich x ist, sonst False

x not in s

False, wenn ein Element in s gleich x ist, sonst True

s + t

Konkatenationsoperator: verkettet s und t

s * n, n * s

s wird n Mal mit sich selbst addiert

s[i]

auf das i-te Element von s zugreifen

s[i:j]

Untersequenz / Teilsequenz aus s von Index i bis j

s[i:j:k]

Untersequenz / Teilsequenz aus s von Index i bis j mit Schritt k

len(s)

Länge von s

min(s)

kleinstes Element in s

max(s)

größtes Element in s

s.index(x[, i[, j]])

Index beim ersten Vorkommnis von x in s (zwischen Index i und j)

s.count(x)

Gesamtzahl aller Vorkommnisse von x in s

Quelle: Python 3.11.3 Documentation

3.1.4. Sets#

Sets sind ungeordnete Sammlungen von Objekten, die gewöhnlich denselben Datentyp haben, aber theoretisch verschiedene Datentypen haben können. Objekte in einem Set dürfen sich nicht wiederholen. In Python gibt es zum einen den Typ set, der veränderbar ist, und den Typ frozenset, der unveränderbar ist. Sets werden zum Beispiel dazu verwendet, um Duplikate aus einer Sequenz zu entfernen, oder Mengenoperationen durchzuführen: zum Beispiel kann man die Vereinigung, die Differenz oder die Schnittmenge zweier Mengen bilden. Sets sind kein sequentieller Datentyp, und die Operationen, die für sequentielle Datentypen definiert sind, können auf Sets nicht angewendet werden.

Beispiel

Fig. 3.3 Beispielobjekt vom Typ Set#

# Leeres Set erstellen - Achtung: {} erstellt ein neues Dictionary!
menge = set()
# Set mit mehreren Objekten verschiedener Datentypen erstellen
menge = {"apfel", 4, True}
# Set mit mehreren Objekten desselben Datentyps erstellen
menge = {"apfel", "banane", "kiwi"}
# Länge
len(menge)
3
# Mitgliedschaftsoperatoren kann man auch auf sets anwenden
"banane" in menge
"banane" not in menge
False
# Überprüfen, ob menge eine Teilmenge von menge_2 ist
menge_2 = {"apfel"}
menge_2.issubset(menge)
True
# Schnittmenge ausgeben lassen
menge_intersect = menge.intersection(menge_2)
print(menge_intersect)
{'apfel'}
# Differenz zwischen menge und menge_2 ausgeben lasen
menge_1 = {"apfel", "banane", "kiwi"}
menge_2 = {"apfel"}
menge_diff = menge_1.difference(menge_2)
print(menge_diff)
{'banane', 'kiwi'}
# Vereinigung der beiden Mengen
menge_1 = {"apfel", "banane", "kiwi"}
menge_2 = {"orange"}
menge_union = menge.union(menge_2)
print(menge_union)
{'orange', 'kiwi', 'apfel', 'banane'}
# Um Objekte mit anderen Datentypen in Sets umzuwandeln, kann man die bereits bekannte Funktion set() verwenden:
# Bei der Umwandlung werden Duplikate entfernt
blumen_lst = ["Rose", "Tulpe", "Tulpe", "Narzisse"]
blumen_set = set(blumen_lst)
print(blumen_set)
{'Tulpe', 'Rose', 'Narzisse'}

3.1.5. Dictionaries#

Python Dictionaries werden dazu verwendet, um Daten als Schlüssel-Wert-Paar zu speichern. Dictionaries sind ähnlich wie Listen, aber die Einträge sind nicht geordnet und anstelle eines Zahlindexes ist jedem Wert ein Schlüssel zugeordnet, über den auf den Wert zugegriffen werden kann. Werte können alle bisher bekannten Datentypen haben und dürfen sich wiederholen, aber Schlüssel müssen unveränderbar und einzigartig sein. Das heißt: Schlüssel können zum Beispiel Strings sein, aber keine Listen. Dictionaries sind genauso wie Sets also kein sequentieller Datentyp, und die Operationen, die für sequentielle Datentypen definiert sind, können auf Dictionaries nicht angewendet werden. Dictionaries werden immer dann verwendet, wenn es sinnvoll ist, dass der Index sinntragend ist.

Beispiel

Fig. 3.4 Beispielobjekt vom Typ Dictionary#

# Leeres Dictionary erstellen
dct = {}
# Dictionary mit mehreren Einträgen erstellen
noten_dict = {"Emma": 3, "Gero": 2, "Hanna": 3 }
# Auf einen Wert zugreifen mit Zugriffsoperator
# Wenn der Schlüssel nicht vorhanden ist, wird eine Fehlermeldung ausgegeben
noten_dict["Emma"]
3
# Auf einen Wert zugreifen mit get()-Methode
# Wenn der Schlüssel nicht vorhanden ist, wird die Nachricht "Schlüssel nicht gefunden" ausgegeben
noten_dict.get("Emma", "Schlüssel nicht gefunden")
3
# Eintrag hinzufügen
noten_dict["Lee"] = 2
# Wert ändern
noten_dict["Emma"] = 2
# Eintrag hinzufügen nur, wenn der Schlüssel noch nicht existiert
noten_dict.setdefault("Samir", 2)
2
# Eintrag entfernen mit Schlüsselwort del
# Wenn der Schlüssel nicht vorhanden ist, wird eine Fehlermeldung ausgegeben
del noten_dict["Emma"]
# Eintrag entfernen und entfernten Wert ausgeben mit pop()-Methode
# Wenn der Schlüssel nicht vorhanden ist, wird die Nachricht "Schlüssel nicht gefunden" ausgegeben
noten_dict.pop("Emma", "Schlüssel nicht gefunden")
'Schlüssel nicht gefunden'
# Mitgliedschaftsoperatoren kann man auch auf Dictionaries anwenden:
# Der Operator wird automatisch auf die Schlüssel angewandt, nicht die Werte)
# Überprüfen, ob ein Schlüssel vorhanden ist (geht natürlich auch mit not in)
"John" in noten_dict
False
# Alle Schlüssel ausgeben lassen
noten_dict.keys()
dict_keys(['Gero', 'Hanna', 'Lee', 'Samir'])
# Alle Werte ausgeben lassen
noten_dict.values()
dict_values([2, 3, 2, 2])
# Überprüfen, ob ein Wert vorhanden ist
2 in noten_dict.values()
True

Note

In diesem Abschnitt wurden zu Illustrationszwecken viele verschiedene Variablennamen verwendet. In der Praxis sollten Variablen aber immer möglichst einheitlich benenannt werden. Heißt: entweder alles Englisch (üblicher) oder alles Deutsch, entweder immer “liste” oder immer “lst”, usw. Vermeiden solltet ihr außerdem unbedingt die Verwendung von “list”, “dict” und “set” als Variablennahmen ohne einen Zusatz wie “noten_dict”, denn diese Wörter sind als Bezeichner für Funktionen zum Erzeugen der entsprechenden Datentypen “reserviert”.

3.1.6. Quellen#

  1. Ana Bell. Tuples, Lists, Aliasing, Mutability, and Cloning. 2016. URL: https://ocw.mit.edu/courses/6-0001-introduction-to-computer-science-and-programming-in-python-fall-2016/resources/lecture-5-tuples-lists-aliasing-mutability-and-cloning/.

  2. Eric Grimson. Recursion and Dictionaries. 2016. URL: https://ocw.mit.edu/courses/6-0001-introduction-to-computer-science-and-programming-in-python-fall-2016/resources/lecture-6-recursion-and-dictionaries/.

  3. Python 3.11.3 Documentation. Built-in Types: Lists. URL: https://docs.python.org/3/library/stdtypes.html#lists.

  4. Python 3.11.3 Documentation. Built-in Types: Mapping Types - dict. URL: https://docs.python.org/3/library/stdtypes.html#dict.

  5. Python 3.11.3 Documentation. Built-in Types: Set Types - set, frozenset. URL: https://docs.python.org/3/library/stdtypes.html#set-types-set-frozenset.

  6. Python 3.11.3 Documentation. Built-in Types: Tuples. URL: https://docs.python.org/3/library/stdtypes.html#tuples.

  7. Python 3.11.3 Documentation. Common Sequence Operations. URL: https://docs.python.org/3/library/stdtypes.html?highlight=class%20str#common-sequence-operations.

  8. Python 3.11.3 Documentation. The Python Tutorial: 5. Data Structures. URL: https://docs.python.org/3/tutorial/datastructures.html#more-on-lists.