Sammeltypen werden benutzt, um mehrere Werte in einer Variablen zu speichern und zu verarbeiten. In Python gibt es vier Sammeltypen, die jeweils eine eigene Klasse sind:
Listen enthalten eine flexible Anzahl von Elementen beliebigen Typs.
Tupel können wie Listen Elemente beliebigen Typs enthalten, sind aber unveränderlich.
Mengen sind ungeordnete Sammlungen, die jedes Element nur einmal enthalten können.
Assoziative Arrays oder Dictionaries sind Zuordnungstabellen, d. h. sie bestehen aus Schlüssel-Wert-Paaren.
In diesem Kapitel werden die vier Sammeltypen zunächst kurz vorgestellt. Anschließend wird die Arbeitsweise insbesondere mit Listen erläutert.
5.1 Listen
Wie alle Typen in Python werden Listen durch Zuweisung erstellt. Bei der Definition einer Liste werden die Elemente durch eckige Klammern [] eingeklammert und mit Kommata , getrennt. Listen können mit dem +-Operator verkettet werden. * verkettet eine Liste n-mal.
text_variable ='abc'liste1 = [1, 'xy', True, text_variable]print(liste1)# Listen können auch Listen enthaltenliste2 = [None, liste1]print(liste2)# Listen können mit + und * verkettet werdenprint(liste1 + liste2)print(liste1 *2)
Eine leere Liste kann durch Zuweisung von [] erstellt werden.
leere_liste = []print(leere_liste)
[]
Slicing: der Zugriffsoperator []
Der Zugriff auf einzelne oder mehrere Elemente einer Liste (und andere Sammeltypen) erfolgt über den Zugriffsoperator []. Ein Ausschnitt aus einem Objekt wird Slice genannt, der Operator heißt deshalb auch Slice Operator.
Zugriff auf einzelne Elemente
Elemente werden über ihren Index, bei 0 beginnend, angesprochen.
print(liste1)print(liste1[0])print(liste1[3])
[1, 'xy', True, 'abc']
1
abc
Auf verschachtelte Listen kann mit zwei aufeinanderfolgenden Zugriffsoperatoren zugegriffen werden. Die Liste liste2 enthält an Indexposition 1 eine Liste mit 4 Elementen.
Mit negativen Indizes können Elemente vom Ende aus angesprochen werden. So entspricht z. B. die -1 dem letzten Element.
print(liste1)print(liste1[-1], liste1[-3])
[1, 'xy', True, 'abc']
abc xy
Zugriff auf mehrere Elemente
Indexbereiche können in der Form [start:stop:step] angesprochen werden. start ist das erste adressierte Element, stopdas erste nicht mehr adressierte Element und step die Schrittweite.
Zugriffsoperator
Ausschnitt
liste[start:stop]
Elemente von start bis stop - 1
liste[:]
Alle Elemente der Liste
liste[start:]
Elemente von start bis zum Ende der Liste
liste[:stop]
Elemente vom Anfang der Liste bis stop - 1
liste[::3]
Auswahl jedes dritten Elements
Negative Werte für start, stop oder step bewirken eine Rückwärtsauswahl von Elementen.
Zugriffsoperator
Ausschnitt
liste[-1]
das letzte Element der Liste
liste[-2:]
die letzten beiden Elemente der Liste
liste[:-2]
alle bis auf die beiden letzten Elemente
liste[::-1]
alle Elemente in umgekehrter Reihenfolge
liste[1::-1]
die ersten beiden Elemente in umgekehrter Reihenfolge
liste[:-3:-1]
die letzten beiden Elemente in umgekehrter Reihenfolge
liste[-3::-1]
alle außer die letzten beiden Elemente in umgekehrter Reihenfolge
Auch aus Zeichenfolgen können mit dem Slice Operator Ausschnitte ausgewählt werden.
print('Ich bin ein string'[::2])print('Hallo Welt'[0:6])print('abc'[::-1])
Ihbnensrn
Hallo
cba
Listenmethoden
Für den Listentyp sind verschiedene Methoden definiert.
Elemente bestimmen
list.index(x, start, stop) gibt die Indexposition des ersten Elements x aus. Die optionalen Argumente start und stop erlauben es, den Suchbereich einzuschränken.
list.count(x) gibt die Häufigkeit von x in der Liste aus.
list.reverse() kehrt die Reihenfolge der Listenelemente um (die Liste wird dadurch verändert!).
list.sort(reverse = False) sortiert die Liste, mit dem optionalen Argument reverse = True absteigend (die Liste wird dadurch verändert!). Die Datentypen innerhalb der Liste müssen sortierbar sein (d. h. alle Elemente sind numerisch oder Zeichen).
print(liste1)liste1.reverse()print(liste1)# True wird als 1 gezähltprint("True wird als 1 gezählt:", liste1.index(1), liste1.count(1))
[1, 'xy', True, 'abc']
['abc', True, 'xy', 1]
True wird als 1 gezählt: 1 2
Elemente einfügen
list.append(x) hängt ein einzelnes Element an das Ende der Liste an.
list.extend(sammeltyp) hängt alle mit sammeltyp übergebenen Elemente an das Ende der Liste an. Der Sammeltyp kann eine Liste, ein Tupel, eine Menge oder ein Dictionary sein.
list.insert(i, x) fügt an der Position i Element x ein.
list.remove(x) entfernt das erste Element x in der Liste und gibt einen ValueError zurück, wenn x nicht in der Liste enthalten ist.
liste.pop(i) entfernt das Element an der Indexposition i. Wird kein Index angegeben, wird das letzte Element entfernt. Die Methode liste.pop(i) gibt die entfernten Elemente zurück.
liste.clear() entfernt alle Elemente einer Liste.
liste1.remove('Hallo')print(liste1)liste1.pop(2)
['abc', True, '12345', 'xy', 1, 'Hallo', 'Welt!']
'12345'
Listen und Listenelemente kopieren
In Python enthalten Listen Daten nicht direkt, sondern bestehen aus Zeigern auf die Speicherorte der enthaltenen Elemente. Wird eine Liste durch Zuweisung einer anderen Liste angelegt, dann werden nicht die Elemente der Liste kopiert, sondern beide Listen greifen dann auf den selben Speicherort zu.
# Kopieren durch Zuweisungliste1 = [1, 'xy', True, text_variable]print("liste1:", liste1, "\n")liste2 = liste1## Ändern eines Elements in liste2liste2[0] ='ABC'print("Auch liste1 hat sich durch die Zuweisung in liste2 verändert:", liste1, "\n")
liste1: [1, 'xy', True, 'abc']
Auch liste1 hat sich durch die Zuweisung in liste2 verändert: ['ABC', 'xy', True, 'abc']
Um eine Liste zu kopieren und ein neues Objekt im Speicher anzulegen, kann die Methode liste.copy() verwendet werden. Auch durch die Verwendung des Zugriffsoperators [:] wird eine neue Liste im Speicher angelegt.
# Verwendung der Methode liste.copy()liste1 = [1, 'xy', True, text_variable]liste2 = liste1.copy()## Ändern eines Elements in liste2liste2[0] ='ABC'print("liste1 bleibt durch die Zuweisung in liste2 unverändert:", liste1, "\n")# Verwendung des Slice Operatorsliste1 = [1, 'xy', True, text_variable]liste2 = liste1[:]## Ändern eines Elements in liste2liste2[0] ='ABC'print("liste1 bleibt durch die Zuweisung in liste2 unverändert:", liste1)
liste1 bleibt durch die Zuweisung in liste2 unverändert: [1, 'xy', True, 'abc']
liste1 bleibt durch die Zuweisung in liste2 unverändert: [1, 'xy', True, 'abc']
Die Kopie von Listenelementen ist in dieser Hinsicht unproblematisch.
# Verwendung des Slice Operatorsliste1 = [1, 'xy', True, text_variable]liste2 = liste1[0:2]# Ändern eines Elements in liste2liste2[0] ='ABC'print("liste1 bleibt durch die Zuweisung in liste2 unverändert:", liste1)
liste1 bleibt durch die Zuweisung in liste2 unverändert: [1, 'xy', True, 'abc']
Um zu überprüfen, ob sich zwei Objekte den Speicherbereich teilen, kann die Objekt-ID mit der Funktion id() verglichen oder die Operatoren is bzw. is not verwendet werden, die die Funktion id() aufrufen.
liste1 = [1, 'xy', True, text_variable]liste2 = liste1print("ID liste1:", id(liste1))print("ID liste2:", id(liste2))print("ID liste1 gleich ID list2:", liste1 is liste2)
ID liste1: 139707108423424
ID liste2: 139707108423424
ID liste1 gleich ID list2: True
Hinweis 5.1: Identität vs. Wertgleichheit
Der Operator is prüft die Identität zweier Objekte und unterscheidet sich dadurch vom logischen Operator ==, der auf Wertgleichheit prüft. Da liste1 und liste2 die gleichen Elemente enthalten, liegen sowohl Identität und Wertgleichheit vor. Der Unterschied von Identität und Wertgleichheit kann anhand eines Werts verdeutlicht werden (Im Code-Beispiel wird eine Syntax-Warnung unterdrückt.).
# Wertgleichheitprint(1==1.0)print(liste1 == liste2, "\n")# Identitätprint(1is1.0)print(liste1 is liste2)
True
True
False
True
Aufgaben Listen
Erstellen Sie eine Liste ‘wochentage’, die die sieben Tage der Woche enthält. Verwenden Sie den Slice-Operator, um eine neue Liste ‘wochenende’ mit den Tagen des Wochenendes zu erstellen. Entfernen Sie die Tage des Wochenendes aus der Liste ‘wochentage’.
4-Tage-Woche: Verwenden Sie Listenmethoden, um den Freitag aus der Liste ‘wochentage’ zu entfernen und der Liste ‘wochenende’ vor dem Samstag hinzuzufügen.
Bestimmen Sie in der Liste zahlen = [34, 12, 0, 67, 23] die Position des Werts 0. Entfernen Sie den Wert aus der Liste und geben Sie die Liste aufsteigend sortiert aus.
Geben Sie nun mit Hilfe des Zugriffsoperators [] die Indexpositionen 1 und 3 der sortierten Liste ‘zahlen’ aus.
Musterlösung kann Marc machen.
Tipp 5.1: Musterlösung
5.2 Tupel
Tupel sind Listen sehr ähnlich, jedoch sind Tupel unveränderbare Datenobjekte. Das heißt, die Elemente eines angelegten Tupels können weder geändert, noch entfernt werden. Auch können keine neuen Elemente zum Tupel hinzugefügt werden.
Tupel werdem mit runden Klammern () erzeugt, die Elemente werden mit einem Komma , getrennt. Ein Tupel mit einem Wert wird mit einem Komma in der Form (wert, ) angelegt. Der Zugriff auf die Elemente eines Tupels ist mit dem Slice-Operator [start:stop:step] möglich. Tupel können mit den Operatoren + und * verkettet werden.
Tupel verhalten sich beim Kopieren gegensätzlich zu Listen. Für Tupel ist die Methode .copy() nicht definiert. Dagegen bewirkt die Kopie mittels dem Zugriffsoperator [:] zwar, dass zwei Tupel auf den selben Speicherplatz zugreifen. Bei der Neuzuweisung eines Tupels legt Python, wie für jedes Objekt, ein neues Objekt im Speicher an.
# Kopieren durch Zuweisungtupel1 = (1, 2, 3)tupel2 = tupel1## Neuzuweisung der Werte von tupel1tupel1 = (4, 5, 6)print(f"Die in tupel2 gespeicherten Werte sind unverändert:\n{tupel1}{tupel2}\n")# Kopieren mit Slice Operatortupel1 = (1, 2, 3)tupel2 = tupel1[:]print(tupel2 is tupel1)## Neuzuweisung der Werte von tupel1tupel1 = (4, 5, 6)print(tupel1, tupel2)
Die in tupel2 gespeicherten Werte sind unverändert:
(4, 5, 6) (1, 2, 3)
True
(4, 5, 6) (1, 2, 3)
5.3 Mengen
In Python können Mengen mit der set() Funktion z. B. aus einer Liste oder aus einem Tupel erzeugt oder durch geschweiften Klammern {} erstellt werden (eine leere Menge kann nur mit set() erzeugt werden, da {} ein leeres Dictionary anlegt). Mengen sind ungeordnete Sammelungen, dementsprechend haben die Elemente keine Reihenfolge.
liste = [1, 1, 5, 3, 3, 4, 2, 'a', 123, 1000, ('tupel', 5)]print("Das Objekt liste als Menge:\n", set(liste))menge = {1, 2, 3, 4, 5, 1000, ('tupel', 5), 'a', 123}print("Die Menge kann auch mit geschweiften Klammern erzeugt werden:", menge, sep ="\n")
Das Objekt liste als Menge:
{1, 2, 3, 4, 5, 1000, ('tupel', 5), 'a', 123}
Die Menge kann auch mit geschweiften Klammern erzeugt werden:
{1, 2, 3, 4, 5, 1000, ('tupel', 5), 'a', 123}
Mengen können beispielsweise für Vergleichsoperationen verwendet werden.
menge_a =set('Python')menge_b =set('ist super')# einzigartige Zeichen in aprint("Menge a:", menge_a)# Zeichen in a, aber nicht in bprint("Menge a - b:", menge_a - menge_b)# Zeichen in a oder bprint("Menge a | b:", menge_a | menge_b)# Zeichen in a und bprint("Menge a & b:", menge_a & menge_b)# Zeichen in a oder b, aber nicht in beiden (XOR)print("Menge a ^ b:", menge_a ^ menge_b)
Mengen verhalten sich wie Tupel mit dem Unterschied, dass die Methode .copy() für Mengen definiert ist. Allerdings kann der Zugriffsoperator [] nicht auf Mengen angewendet werden.
# Kopieren durch Zuweisungset1 = {1, 2, 3}set2 = set1print(set1 is set2)## Neuzuweisen von set1set1 = {4, 5, 6}print(f"Die in set2 gespeicherten Werte sind unverändert:\n{set1}{set2}")# Kopieren durch Methode .copy()set1 = {1, 2, 3}set2 = set1.copy()print(set1 is set2)## Neuzuweisen von set1set1 = {4, 5, 6}print(f"Die in set2 gespeicherten Werte sind unverändert:\n{set1}{set2}")
True
Die in set2 gespeicherten Werte sind unverändert:
{4, 5, 6} {1, 2, 3}
False
Die in set2 gespeicherten Werte sind unverändert:
{4, 5, 6} {1, 2, 3}
5.4 Dictionaries
Dictionaries bestehen aus Schlüssel-Wert-Paaren. Die Schlüssel können Zahlen oder Zeichenketten sein, jeder Schlüssel darf nur einmal vorkommen. Dictionaries werden mit geschweiften Klammern {} definiert. Die Schlüssel und deren zugehörigen Werte werden mit einem Doppelpunkt : getrennt. Der Zugriff auf die Werte erfolgt mit dem Zugriffsoperator [], welcher den oder die Schlüssel beinhaltet. Ein Zugriff über die Indexposition der Schlüssel ist nicht möglich, da Zahlen als Schlüssel interpretiert werden.
Auf die Schlüssel eines Dictionaries kann über die Methode dictionary.keys(), auf die Werte mittels der Methode dictionary.values() zugegriffen werden.
Dictionaries verhalten sich beim Kopieren wie Listen, das heißt beim Kopieren durch Zuweisung teilen sich Dictionaries den Speicherbereich.
# Kopieren durch Zuweisungprint("dictionary:", dictionary1, "\n")dictionary2 = dictionary1## Ändern eines Elements in dictionary2dictionary2[1] ='ABC'print("Auch dictionary1 hat sich durch die Zuweisung in dictionary2 verändert:\n", dictionary1, "\n")# Verwendung der Methode dictionary.copy()dictionary1 = {1: 'abc', 'b': [1, 2, 3], 'c': ('tupel', 5, 6)}dictionary2 = dictionary1.copy()## Ändern eines Elements in dictionary2dictionary2[1] ='ABC'print("dictionary1 bleibt durch die Zuweisung in dictionary2 unverändert:\n", dictionary1, "\n")
dictionary: {1: 'abc', 'b': [1, 2, 3], 'c': ('tupel', 5, 6)}
Auch dictionary1 hat sich durch die Zuweisung in dictionary2 verändert:
{1: 'ABC', 'b': [1, 2, 3], 'c': ('tupel', 5, 6)}
dictionary1 bleibt durch die Zuweisung in dictionary2 unverändert:
{1: 'abc', 'b': [1, 2, 3], 'c': ('tupel', 5, 6)}
5.5 Übersicht Sammeltypen
Merkmal
Listen
Tupel
Mengen
Dictionary
Beschreibung
flexible Anzahl von Elementen beliebigen Typs
Elemente beliebigen Typs, unveränderlich
ungeordnete Sammlung, jedes Element nur einmal enthalten
Zuordnungstabelle aus Schlüssel-Wert-Paaren
Speicherbereich bei Zuweisung geteilt
ja
ja (aber unveränderlich)
ja (aber Zugriffsoperator nicht anwendbar)
ja
Methode .copy() definiert
ja
nein
ja
ja
Slice-Operator anwendbar
ja
ja
nein
ja (nach Schlüssel)
5.6 Löschen: das Schlüsselwort del
Um Sammeltypen, Elemente oder Slices zu löschen kann das Schlüsselwort del verwendet werden.
# Löschen einer Listedel liste1# Löschen eines Indexbereichs aus einer Listeprint("Liste vor dem Löschen:", liste2)del liste2[1:3]print("Liste nach dem Löschen:", liste2)# Löschen eines Schlüsselworts aus einem Dictionaryprint("Dictionary vor dem Löschen", dictionary1)del dictionary1[1]print("Dictionary nach dem Löschen", dictionary1)
Liste vor dem Löschen: [1, 'xy', True, 'abc']
Liste nach dem Löschen: [1, 'abc']
Dictionary vor dem Löschen {1: 'abc', 'b': [1, 2, 3], 'c': ('tupel', 5, 6)}
Dictionary nach dem Löschen {'b': [1, 2, 3], 'c': ('tupel', 5, 6)}
5.7 Funktionen
Die Sammeltypen können ineinander umgewandelt werden.
Einige praktische Funktionen lassen sich auch auf Sammeltypen anwenden:
len() gibt die Anzahl der Elemente in einem Sammeltyp zurück.
min(), max(), sum() gibt das Minimum, Maximum bzw. die Summe eines Sammeltyps zurück (bei Dictionaries wird die Anzahl der Schlüssel gezählt).
5.8 Operationen: Verwendung von Schleifen
Um arithmetische und logische Operatoren auf die in einem Sammeltyp gespeicherten Elemente anzuwenden, wird eine for-Schleife verwendet. Im folgenden Beispiel wird eine Liste ‘zahlen’ durchlaufen, die darin gespeicherten Zahlen quadriert und das jeweilige Ergebnis an die Liste ‘quadratzahlen’ angehängt. Auch wird geprüft, ob die quadrierten Zahlen ganzzahlig durch 3 teilbar sind und das Prüfergebnis in einer Liste ‘modulo_3’ gespeichert.
zahlen =list(range(1, 11))quadratzahlen = [] # die Liste muss vor der Schleife angelegt werdenmodulo_3 = [] # leere Liste vor der Schleife anlegenfor zahl in zahlen: quadratzahl = zahl **2 quadratzahlen.append(quadratzahl) modulo_3.append(quadratzahl %3==0)print(quadratzahlen)print(modulo_3)
Modifizieren Sie den Programmcode in Code-Block 5.1 so, dass nur die Quadratzahlen gespeichert werden, die ganzzahlig durch 3 teilbar sind.
Umrechnung von Geschwindigkeiten
Erstellen Sie ein Skript, welches eine Umrechnungstabelle für Geschwindigkeiten erzeugt. Folgende Randbedingungen sollen beachtet werden:
Die Umrechnung soll von km/h in m/s erfolgen.
Der Start- und Endwert soll in km/h frei wählbar sein, wobei beide ganzzahlig sein sollen.
Die Anzahl der Umrechnungspunkte soll definiert werden können und die Zwischenschritte (in km/h) immer als ganze Zahlen ausgegeben werden.
Tipp: In Ihrem Skript können Sie die Funktion input() verwenden, um Werte per Eingabe zu erfassen.
Sortieren: Gegeben ist die Liste meine_liste = list(range(9, 0, -1)). Diese soll mittels for-Schleifen sortiert werden.
Tipp 5.2: Musterlösung Aufgaben Sammeltypen
Ganzzahlig durch 3 teilbare Quadratzahlen
zahlen =list(range(1, 11))quadratzahlen = [] # die Liste muss vor der Schleife angelegt werdenmodulo_3 = [] # leere Liste vor der Schleife anlegenfor zahl in zahlen: quadratzahl = zahl **2if quadratzahl %3==0: quadratzahlen.append(quadratzahl)print(quadratzahlen)
[9, 36, 81]
Umrechnung von Geschwindigkeiten
# Freie Eingabe## start = int(input("Startwert in Kilometer pro Stunde eingeben."))## ende = int(input("Endwert in Kilometer pro Stunde eingeben."))## ausgabeschritte = int(input("Anzahl auszugebener Schritte ein geben."))# Fixe Werte für die Lösungstart =5ende =107ausgabeschritte =8# Liste für km erstellenschrittweite = (ende - start) / (ausgabeschritte -1)liste_km = []for i inrange(ausgabeschritte): liste_km.append(round(start + i * schrittweite))# Umrechnung# meter = 1000 * kilometer# Sekunde = Stunde * 60 * 60liste_m = []for wert in liste_km: liste_m.append(round((wert *1000) / (60*60), 2))# Ausgabeprint(f"Schrittweite: {schrittweite:.2f}")print("Kilometer pro Stunde")print(liste_km)print("Meter pro Sekunde")print(liste_m)
Schrittweite: 14.57
Kilometer pro Stunde
[5, 20, 34, 49, 63, 78, 92, 107]
Meter pro Sekunde
[1.39, 5.56, 9.44, 13.61, 17.5, 21.67, 25.56, 29.72]
Sortieren: Bubble Sort Algorithmus
# statische Liste, Textausgabemeine_liste =list(range(9, 0, -1))iflen(meine_liste) >1: print("Liste zu Beginn\t\t :", meine_liste)# äußere Schleife Schritt =0for i inrange(len(meine_liste) -1):# innere Schleifefor j inrange(len(meine_liste) -1):if meine_liste[j] > meine_liste[j +1]: meine_liste[j], meine_liste[j +1] = meine_liste[j +1], meine_liste[j] Schritt +=1print("Liste nach Schritt ", Schritt, ":", meine_liste)print("\nListe sortiert:", *meine_liste) # * unterdrückt die Kommas zwischen den Listenelementenelse:print("Die Liste muss mindenstens zwei Elemente enthalten!")
Liste zu Beginn : [9, 8, 7, 6, 5, 4, 3, 2, 1]
Liste nach Schritt 1 : [8, 7, 6, 5, 4, 3, 2, 1, 9]
Liste nach Schritt 2 : [7, 6, 5, 4, 3, 2, 1, 8, 9]
Liste nach Schritt 3 : [6, 5, 4, 3, 2, 1, 7, 8, 9]
Liste nach Schritt 4 : [5, 4, 3, 2, 1, 6, 7, 8, 9]
Liste nach Schritt 5 : [4, 3, 2, 1, 5, 6, 7, 8, 9]
Liste nach Schritt 6 : [3, 2, 1, 4, 5, 6, 7, 8, 9]
Liste nach Schritt 7 : [2, 1, 3, 4, 5, 6, 7, 8, 9]
Liste nach Schritt 8 : [1, 2, 3, 4, 5, 6, 7, 8, 9]
Liste sortiert: 1 2 3 4 5 6 7 8 9