5. Datenstrukturen¶
In diesem Kapitel werden einige Dinge, die Sie bereits kennengelernt haben, näher erläutert, und es werden zudem einige neue Aspekte hinzugefügt.
5.1. Mehr zum Thema Listen¶
Der Datentyp list verfügt über einige weitere Methoden. Hier sind alle Methoden von Listenobjekten aufgeführt:
- list.append(value, /)
Füge einen Eintrag am Ende der Liste hinzu. Ähnlich wie bei
a[len(a):] = [x].
- list.extend(iterable, /)
Erweitere die Liste, indem du alle Elemente aus der iterierbaren Struktur anhängst. Ähnlich wie bei
a[len(a):] = iterable.
- list.insert(index, value, /)
Fügt ein Element an einer bestimmten Position ein. Das erste Argument ist der Index des Elements, vor dem eingefügt werden soll. Daher fügt
a.insert(0, x)am Anfang der Liste ein, unda.insert(len(a), x)entsprichta.append(x).
- list.remove(value, /)
Entferne das erste Element aus der Liste, dessen Wert value entspricht. Wenn kein solches Element vorhanden ist, wird eine
ValueErrorausgelöst.
- list.pop(index=-1, /)
Entfernt das Element an der angegebenen Position aus der Liste und gibt es zurück. Wenn kein Index angegeben wird, entfernt
a.pop()das letzte Element der Liste und gibt es zurück. Es löst eineIndexErroraus, wenn die Liste leer ist oder der Index außerhalb des Listenbereichs liegt.
- list.clear()
Entferne alle Elemente aus der Liste. Ähnlich wie bei
del a[:].
- list.index(value[, start[, stop]])
Gibt den nullbasierten Index des ersten Vorkommens von value in der Liste zurück. Löst eine Ausnahme vom Typ
ValueErroraus, wenn kein entsprechendes Element vorhanden ist.Die optionalen Argumente start und end werden wie in der Slice-Notation interpretiert und dienen dazu, die Suche auf eine bestimmte Teilfolge der Liste zu beschränken. Der zurückgegebene Index wird relativ zum Anfang der vollständigen Folge und nicht relativ zum Argument start berechnet.
- list.count(value, /)
Gibt die Anzahl der Vorkommen von value in der Liste zurück.
- list.sort(*, key=None, reverse=False)
Sortiere die Elemente der Liste an Ort und Stelle (die Argumente können zur Anpassung der Sortierung verwendet werden; eine Erläuterung findest du unter
sorted()).
- list.reverse()
Die Elemente der Liste an Ort und Stelle in umgekehrter Reihenfolge anordnen.
- list.copy()
Gibt eine flache Kopie der Liste zurück. Ähnlich wie bei
a[:].
Ein Beispiel, das die meisten Methoden der Liste verwendet:
>>> fruits = ['Orange', 'Apfel', 'Birne', 'Banane', 'Kiwi', 'Apfel', 'Banane']
>>> fruits.count('Apfel')
2
>>> fruits.count('Mandarine')
0
>>> fruits.index('Banane')
3
>>> fruits.index('banana', 4) # Die nächste Banane ab Position 4 finden
6
>>> fruits.reverse()
>>> fruits
['banana', 'apple', 'kiwi', 'banana', 'pear', 'apple', 'orange']
>>> fruits.append('traube')
>>> fruits
['banane', 'apfel', 'kiwi', 'banane', 'birne', 'apfel', 'orange', 'traube']
>>> fruits.sort()
>>> fruits
['Apfel', 'Apfel', 'Banane', 'Banane', 'Traube', 'Kiwi', 'Orange', 'Birne']
>>> fruits.pop()
'Birne'
Vielleicht ist Ihnen aufgefallen, dass bei Methoden wie insert, remove oder sort, die lediglich die Liste verändern, kein Rückgabewert ausgegeben wird – sie geben den Standardwert None zurück. [1] Dies ist ein Entwurfsprinzip für alle veränderbaren Datenstrukturen in Python.
Außerdem wird Ihnen vielleicht auffallen, dass nicht alle Daten sortiert oder verglichen werden können. So lässt sich beispielsweise [None, 'hello', 10] nicht sortieren, da Ganzzahlen nicht mit Zeichenketten verglichen werden können und None nicht mit anderen Typen verglichen werden kann. Zudem gibt es einige Typen, für die keine definierte Ordnungsrelation existiert. So ist beispielsweise 3+4j < 5+7j kein gültiger Vergleich.
5.1.1. Listen als Stapel verwenden¶
Die Listenmethoden machen es sehr einfach, eine Liste als Stapel zu verwenden, bei dem das zuletzt hinzugefügte Element als erstes wieder abgerufen wird („Last-in, First-out“). Um ein Element oben auf den Stapel zu setzen, verwenden Sie append(). Um ein Element von der Spitze des Stapels abzurufen, verwenden Sie pop() ohne expliziten Index. Beispiel:
>>> stack = [3, 4, 5]
>>> stack.append(6)
>>> stack.append(7)
>>> stack
[3, 4, 5, 6, 7]
>>> stack.pop()
7
>>> stack
[3, 4, 5, 6]
>>> stack.pop()
6
>>> stack.pop()
5
>>> stack
[3, 4]
5.1.2. Listen als Warteschlangen verwenden¶
It is also possible to use a list as a queue, where the first element added is the first element retrieved („first-in, first-out“); however, lists are not efficient for this purpose. While appends and pops from the end of list are fast, doing inserts or pops from the beginning of a list is slow (because all of the other elements have to be shifted by one).
Um eine Warteschlange zu implementieren, verwenden Sie collections.deque “, das für schnelles Hinzufügen und Entnehmen von beiden Enden ausgelegt ist. Beispiel:
>>> from collections import deque
>>> queue = deque(["Eric", "John", "Michael"])
>>> queue.append("Terry") # Terry kommt an
>>> queue.append("Graham") # Graham kommt an
>>> queue.popleft() # Der Erste, der angekommen ist, verlässt nun die Warteschlange
'Eric'
>>> queue.popleft() # Der Zweite, der angekommen ist, verlässt nun die Warteschlange
'John'
>>> queue # Verbleibende Warteschlange in der Reihenfolge der Ankunft
deque(['Michael', 'Terry', 'Graham'])
5.1.3. Listen-Abstraktion¶
Listen-Abstraktion bieten eine prägnante Möglichkeit, Listen zu erstellen. Häufige Anwendungsfälle sind die Erstellung neuer Listen, bei denen jedes Element das Ergebnis bestimmter Operationen ist, die auf jedes Element einer anderen Sequenz oder eines anderen iterierbaren Objekts angewendet werden, oder die Erstellung einer Teilsequenz aus den Elementen, die eine bestimmte Bedingung erfüllen.
Nehmen wir zum Beispiel an, wir möchten eine Liste von Quadraten erstellen, etwa wie folgt:
>>> squares = []
>>> for x in range(10):
... squares.append(x**2)
...
>>> squares
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
Beachten Sie, dass dadurch eine Variable namens x angelegt (oder überschrieben) wird, die auch nach Abschluss der Schleife noch vorhanden ist. Wir können die Liste der Quadrate ohne Nebenwirkungen wie folgt berechnen:
Quadrate = list(map(lambda x: x**2, range(10)))
oder, gleichbedeutend:
Quadrate = [x**2 for x in range(10)]
was prägnanter und besser lesbar ist.
Eine Listenkomprimierung besteht aus Klammern, die einen Ausdruck enthalten, gefolgt von einer for “-Klausel und anschließend null oder mehr for “- oder if “-Klauseln. Das Ergebnis ist eine neue Liste, die sich aus der Auswertung des Ausdrucks im Kontext der darauf folgenden for “- und if “-Klauseln ergibt. Diese Listenkomprimierung kombiniert beispielsweise die Elemente zweier Listen, sofern sie nicht identisch sind:
>>> [(x, y) für x in [1, 2, 3] für y in [3, 1, 4], wenn x != y]
[(1, 3), (1, 4), (2, 3), (2, 1), (2, 4), (3, 1), (3, 4)]
und das entspricht:
>>> combs = []
>>> for x in [1, 2, 3]:
... for y in [3, 1, 4]:
... if x != y:
... combs.append((x, y))
...
>>> combs
[(1, 3), (1, 4), (2, 3), (2, 1), (2, 4), (3, 1), (3, 4)]
Beachten Sie, dass die Reihenfolge der Anweisungen for und if in beiden Codeausschnitten identisch ist.
Wenn es sich bei dem Ausdruck um ein Tupel handelt (z. B. (x, y) im vorherigen Beispiel), muss es in Klammern gesetzt werden.
>>> vec = [-4, -2, 0, 2, 4]
>>> # Erstelle eine neue Liste, in der die Werte verdoppelt sind
>>> [x*2 for x in vec]
[-8, -4, 0, 4, 8]
>>> # Filtere die Liste, um negative Zahlen auszuschließen
>>> [x for x in vec if x >= 0]
[0, 2, 4]
>>> # Eine Funktion auf alle Elemente anwenden
>>> [abs(x) for x in vec]
[4, 2, 0, 2, 4]
>>> # Eine Methode auf jedes Element anwenden
>>> freshfruit = [' banana', ' loganberry ', 'passion fruit ']
>>> [weapon.strip() for weapon in freshfruit]
['banana', 'loganberry', 'passion fruit']
>>> # Eine Liste von 2-Tupeln wie (Zahl, Quadrat) erstellen
>>> [(x, x**2) for x in range(6)]
[(0, 0), (1, 1), (2, 4), (3, 9), (4, 16), (5, 25)]
>>> # Das Tupel muss in Klammern gesetzt werden, sonst wird ein Fehler ausgelöst
>>> [x, x**2 for x in range(6)]
Datei "<stdin>", Zeile 1
[x, x**2 for x in range(6)]
^^^^^^^
SyntaxError: Hast du die Klammern um das Ziel der List Comprehension vergessen?
>>> # Eine Liste mithilfe einer List Comprehension mit zwei "for"-Schleifen abflachen
>>> vec = [[1,2,3], [4,5,6], [7,8,9]]
>>> [num for elem in vec for num in elem]
[1, 2, 3, 4, 5, 6, 7, 8, 9]
Listen-Abstraktionen können komplexe Ausdrücke und verschachtelte Funktionen enthalten:
>>> from math import pi
>>> [str(round(pi, i)) for i in range(1, 6)]
['3,1', '3,14', '3,142', '3,1416', '3,14159']
5.1.4. Verschachtelte Listen-Abstraktion¶
Der erste Ausdruck in einer Listen-Abstraktion kann ein beliebiger Ausdruck sein, einschließlich einer weiteren Listen-Abstraktion.
Betrachte das folgende Beispiel einer 3×4-Matrix, die als Liste aus drei Listen der Länge 4 implementiert ist:
>>> matrix = [
... [1, 2, 3, 4],
... [5, 6, 7, 8],
... [9, 10, 11, 12],
... ]
Die folgende Listen-Abstraktion transponiert Zeilen und Spalten:
>>> [[row[i] for row in matrix] for i in range(4)]
[[1, 5, 9], [2, 6, 10], [3, 7, 11], [4, 8, 12]]
Wie wir im vorigen Abschnitt gesehen haben, wird die innere Listenauswertung im Kontext des darauf folgenden for ausgewertet, sodass dieses Beispiel gleichbedeutend ist mit:
>>> transposed = []
>>> for i in range(4):
... transposed.append([row[i] for row in matrix])
...
>>> transposed
[[1, 5, 9], [2, 6, 10], [3, 7, 11], [4, 8, 12]]
was wiederum dasselbe ist wie:
>>> transposed = []
>>> for i in range(4):
... # Die folgenden 3 Zeilen implementieren die verschachtelte Listenkomposition
... transposed_row = []
... for row in matrix:
... transposed_row.append(row[i])
... transponiert.append(transponierte_Zeile)
...
>>> transponiert
[[1, 5, 9], [2, 6, 10], [3, 7, 11], [4, 8, 12]]
In der Praxis sollten Sie integrierte Funktionen komplexen Ablaufanweisungen vorziehen. Die Funktion zip() eignet sich hervorragend für diesen Anwendungsfall:
>>> list(zip(*matrix))
[(1, 5, 9), (2, 6, 10), (3, 7, 11), (4, 8, 12)]
Weitere Informationen zum Sternchen in dieser Zeile finden Sie unter Entpacken von Argumentlisten.
5.2. Die Erklärung der del “¶
Es gibt eine Möglichkeit, ein Element anhand seines Indexes statt seines Wertes aus einer Liste zu entfernen: die Anweisung del “. Diese unterscheidet sich von der Methode pop() “, die einen Wert zurückgibt. Die Anweisung del kann auch verwendet werden, um Teilmengen aus einer Liste zu entfernen oder die gesamte Liste zu leeren (was wir zuvor durch die Zuweisung einer leeren Liste zur Teilmenge getan haben). Zum Beispiel:
>>> a = [-1, 1, 66,25, 333, 333, 1234,5]
>>> del a[0]
>>> a
[1, 66,25, 333, 333, 1234,5]
>>> del a[2:4]
>>> a
[1, 66,25, 1234,5]
>>> del a[:]
>>> a
[]
del kann auch zum Löschen ganzer Variablen verwendet werden:
>>> del a
Der Verweis auf den Namen a ist hier ein Fehler (zumindest solange, bis ihm ein anderer Wert zugewiesen wird). Wir werden später noch weitere Verwendungsmöglichkeiten für del finden.
5.3. Tupel und Sequenzen¶
Wir haben gesehen, dass Listen und Zeichenketten viele gemeinsame Eigenschaften haben, wie beispielsweise Indizierungs- und Ausschnittoperationen. Sie sind zwei Beispiele für Sequenz-Datentypen (siehe Sequenztypen – list, tuple, range). Da Python eine sich weiterentwickelnde Sprache ist, können weitere Sequenz-Datentypen hinzukommen. Es gibt außerdem einen weiteren standardmäßigen Sequenz-Datentyp: das Tupel.
Ein Tupel besteht aus einer Reihe von Werten, die durch Kommas getrennt sind, zum Beispiel:
>>> t = 12345, 54321, 'hello!'
>>> t[0]
12345
>>> t
(12345, 54321, 'hello!')
>>> # Tupel können verschachtelt sein:
>>> u = t, (1, 2, 3, 4, 5)
>>> u
((12345, 54321, 'hello!'), (1, 2, 3, 4, 5))
>>> # Tupel sind unveränderlich:
>>> t[0] = 88888
Traceback (letzter Aufruf zuletzt):
Datei "<stdin>", Zeile 1, in <module>
TypeError: Das Objekt "tuple" unterstützt keine Elementzuweisung
>>> # können jedoch veränderbare Objekte enthalten:
>>> v = ([1, 2, 3], [3, 2, 1])
>>> v
([1, 2, 3], [3, 2, 1])
Wie Sie sehen, werden Tupel in der Ausgabe immer in Klammern gesetzt, damit verschachtelte Tupel korrekt interpretiert werden; sie können mit oder ohne umschließende Klammern eingegeben werden, obwohl Klammern oft ohnehin erforderlich sind (wenn das Tupel Teil eines größeren Ausdrucks ist). Es ist nicht möglich, den einzelnen Elementen eines Tupels Werte zuzuweisen; es ist jedoch möglich, Tupel zu erstellen, die veränderbare Objekte wie beispielsweise Listen enthalten.
Auch wenn Tupel auf den ersten Blick Listen ähneln mögen, werden sie oft in anderen Situationen und für andere Zwecke verwendet. Tupel sind unveränderlich und enthalten in der Regel eine heterogene Folge von Elementen, auf die über Entpacken (siehe weiter unten in diesem Abschnitt) oder Indizierung (oder im Fall von namedtuples sogar über Attribute) zugegriffen wird. Listen sind veränderlich, und ihre Elemente sind in der Regel homogen; der Zugriff erfolgt durch Iteration über die Liste.
Ein besonderes Problem stellt die Bildung von Tupeln dar, die 0 oder 1 Element enthalten: Die Syntax weist hierfür einige zusätzliche Besonderheiten auf. Leere Tupel werden durch ein leeres Klammerpaar gebildet; ein Tupel mit einem Element wird gebildet, indem man einem Wert ein Komma nachsetzt (es reicht nicht aus, einen einzelnen Wert in Klammern zu setzen). Unschön, aber effektiv. Zum Beispiel:
>>> empty = ()
>>> singleton = 'hello', # <-- note trailing comma
>>> len(empty)
0
>>> len(singleton)
1
>>> singleton
('hello',)
Die Anweisung t = 12345, 54321, 'hello!' ist ein Beispiel für Tupel-Packing: Die Werte 12345 “, 54321 und 'hello!' “ werden in einem Tupel zusammengefasst. Auch die umgekehrte Operation ist möglich:
>>> x, y, z = t
Dies wird passenderweise als Sequenz-Entpackung bezeichnet und funktioniert für jede beliebige Sequenz auf der rechten Seite. Für die Sequenz-Entpackung muss die Anzahl der Variablen auf der linken Seite des Gleichheitszeichens der Anzahl der Elemente in der Sequenz entsprechen. Beachten Sie, dass die Mehrfachzuweisung im Grunde nur eine Kombination aus Tupel-Packing und Sequenz-Unpacking ist.
5.4. Sets¶
Python enthält außerdem einen Datentyp für Mengen. Eine Menge ist eine ungeordnete Sammlung ohne doppelte Elemente. Zu den grundlegenden Anwendungsbereichen gehören die Überprüfung der Zugehörigkeit zu einer Menge und das Entfernen doppelter Einträge. Mengenobjekte unterstützen zudem mathematische Operationen wie Vereinigung, Schnittmenge, Differenz und symmetrische Differenz.
Zum Erstellen von Mengen können geschweifte Klammern oder die Funktion set() verwendet werden. Hinweis: Um eine leere Menge zu erstellen, müssen Sie set() verwenden, nicht {} “; Letzteres erstellt ein leeres Wörterbuch, eine Datenstruktur, die wir im nächsten Abschnitt behandeln.
Da Mengen ungeordnet sind, kann es beim Durchlaufen oder Ausgeben der Elemente vorkommen, dass diese in einer anderen Reihenfolge angezeigt werden, als Sie erwarten.
Hier eine kurze Demonstration:
>>> basket = {'Apfel', 'Orange', 'Apfel', 'Birne', 'Orange', 'Banane'}
>>> print(basket) # zeigt, dass Duplikate entfernt wurden
{'Orange', 'Banane', 'Birne', 'Apfel'}
>>> 'orange' in basket # schnelle Zugehörigkeitsprüfung
True
>>> 'crabgrass' in basket
False
>>> # Demonstration von Mengenoperationen mit eindeutigen Buchstaben aus zwei Wörtern
>>>
>>> a = set('abracadabra')
>>> b = set('alacazam')
>>> a # eindeutige Buchstaben in a
{'a', 'r', 'b', 'c', 'd'}
>>> a - b # Buchstaben in a, die nicht in b vorkommen
{'r', 'd', 'b'}
>>> a | b # Buchstaben in a oder b oder in beiden
{'a', 'c', 'r', 'd', 'b', 'm', 'z', 'l'}
>>> a & b # Buchstaben, die sowohl in a als auch in b vorkommen
{'a', 'c'}
>>> a ^ b # Buchstaben, die entweder in a oder in b vorkommen, aber nicht in beiden
{'r', 'd', 'b', 'm', 'z', 'l'}
Ähnlich wie bei den Listenkomprimierungen werden auch Mengekomprimierungen unterstützt:
>>> a = {x for x in 'abracadabra' if x not in 'abc'}
>>> a
{'r', 'd'}
5.5. Wörterbücher¶
Ein weiterer nützlicher, in Python integrierter Datentyp ist das Wörterbuch (siehe Mapping-Typen – dict). Wörterbücher werden in anderen Sprachen manchmal als „assoziative Speicher“ oder „assoziative Arrays“ bezeichnet. Im Gegensatz zu Sequenzen, die durch einen Zahlenbereich indiziert werden, werden Dictionaries durch Schlüssel indiziert, die von jedem unveränderlichen Typ sein können; Zeichenketten und Zahlen können immer als Schlüssel verwendet werden. Tupel können als Schlüssel verwendet werden, wenn sie ausschließlich Zeichenketten, Zahlen oder Tupel enthalten; enthält ein Tupel direkt oder indirekt ein veränderbliches Objekt, kann es nicht als Schlüssel verwendet werden. Listen können nicht als Schlüssel verwendet werden, da sie durch Indexzuweisungen, Slice-Zuweisungen oder Methoden wie append() und extend() an Ort und Stelle verändert werden können.
Man kann sich ein Wörterbuch am besten als eine Menge von Schlüssel:Wert-Paaren vorstellen, wobei die Schlüssel (innerhalb eines Wörterbuchs) eindeutig sein müssen. Ein Paar geschweifter Klammern erstellt ein leeres Wörterbuch: {}. Durch Einfügen einer durch Kommas getrennten Liste von Schlüssel:Wert-Paaren innerhalb der geschweiften Klammern werden dem Wörterbuch anfängliche Schlüssel:Wert-Paare hinzugefügt; auf diese Weise werden Wörterbücher auch bei der Ausgabe dargestellt.
Die wichtigsten Operationen in einem Wörterbuch sind das Speichern eines Werts unter einem bestimmten Schlüssel und das Abrufen des Werts anhand des Schlüssels. Es ist außerdem möglich, ein Schlüssel-Wert-Paar mit ` del` zu löschen. Wenn Sie einen Wert unter einem Schlüssel speichern, der bereits verwendet wird, wird der alte, diesem Schlüssel zugeordnete Wert verworfen.
Der Versuch, einen Wert für einen nicht vorhandenen Schlüssel mittels Indexierung abzurufen (d[key]), löst einen KeyError aus. Um diesen Fehler beim Zugriff auf einen möglicherweise nicht vorhandenen Schlüssel zu vermeiden, verwenden Sie stattdessen die Methode get(), die None (oder einen angegebenen Standardwert) zurückgibt, wenn der Schlüssel nicht im Wörterbuch enthalten ist.
Wendet man list(d) auf ein Wörterbuch an, wird eine Liste aller im Wörterbuch verwendeten Schlüssel in der Reihenfolge ihrer Einfügung zurückgegeben (wenn Sie die Liste sortiert haben möchten, verwenden Sie stattdessen einfach sorted(d) “). Um zu prüfen, ob ein einzelner Schlüssel im Wörterbuch enthalten ist, verwenden Sie das Schlüsselwort in .
Hier ist ein kleines Beispiel, bei dem ein Wörterbuch verwendet wird:
>>> tel = {'jack': 4098, 'sape': 4139}
>>> tel['guido'] = 4127
>>> tel
{'jack': 4098, 'sape': 4139, 'guido': 4127}
>>> tel['jack']
4098
>>> tel['irv']
Traceback (letzter Aufruf zuletzt):
Datei "<stdin>", Zeile 1, in <module>
KeyError: 'irv'
>>> print(tel.get('irv'))
None
>>> del tel['sape']
>>> tel['irv'] = 4127
>>> tel
{'jack': 4098, 'guido': 4127, 'irv': 4127}
>>> list(tel)
['jack', 'guido', 'irv']
>>> sorted(tel)
['guido', 'irv', 'jack']
>>> 'guido' in tel
True
>>> 'jack' not in tel
False
Der Konstruktor ` dict() ` erstellt Wörterbücher direkt aus Sequenzen von Schlüssel-Wert-Paaren:
>>> dict([('sape', 4139), ('guido', 4127), ('jack', 4098)])
{'sape': 4139, 'guido': 4127, 'jack': 4098}
Darüber hinaus können Dict-Comprehensions verwendet werden, um Wörterbücher aus beliebigen Schlüssel- und Wert-Ausdrücken zu erstellen:
>>> {x: x**2 for x in (2, 4, 6)}
{2: 4, 4: 16, 6: 36}
Wenn es sich bei den Schlüsseln um einfache Zeichenfolgen handelt, ist es manchmal einfacher, Paare mithilfe von Schlüsselwortargumenten anzugeben:
>>> dict(sape=4139, guido=4127, jack=4098)
{'sape': 4139, 'guido': 4127, 'jack': 4098}
5.6. Schleifentechniken¶
Beim Durchlaufen von Wörterbüchern können der Schlüssel und der zugehörige Wert mithilfe der Methode items() gleichzeitig abgerufen werden.
>>> knights = {'gallahad': 'der Reine', 'robin': 'der Tapfere'}
>>> for k, v in knights.items():
... print(k, v)
...
gallahad der Reine
robin der Tapfere
Beim Durchlaufen einer Sequenz können der Positionsindex und der zugehörige Wert mithilfe der Funktion enumerate() gleichzeitig abgerufen werden.
>>> for i, v in enumerate(['tic', 'tac', 'toe']):
... print(i, v)
...
0 tic
1 tac
2 toe
Um zwei oder mehr Sequenzen gleichzeitig zu durchlaufen, können die Einträge mit der Funktion zip() gepaart werden.
>>> Fragen = ['Name', 'Aufgabe', 'Lieblingsfarbe']
>>> Antworten = ['Lancelot', 'der Heilige Gral', 'blau']
>>> for q, a in zip(Fragen, Antworten):
... print('Wie heißt du {0}? Du heißt {1}.'.format(q, a))
...
Wie heißt du? Du heißt Lancelot.
Was ist deine Aufgabe? Es ist der Heilige Gral.
Was ist deine Lieblingsfarbe? Es ist Blau.
Um eine Folge in umgekehrter Reihenfolge zu durchlaufen, geben Sie zunächst die Folge in Vorwärtsrichtung an und rufen Sie anschließend die Funktion reversed() auf.
>>> for i in reversed(range(1, 10, 2)):
... print(i)
...
9
7
5
3
1
Um eine Folge in sortierter Reihenfolge zu durchlaufen, verwenden Sie die Funktion sorted() “, die eine neue sortierte Liste zurückgibt, während die Quelle unverändert bleibt.
>>> basket = ['Apfel', 'Orange', 'Apfel', 'Birne', 'Orange', 'Banane']
>>> for i in sorted(basket):
... print(i)
...
Apfel
Apfel
Banane
Orange
Orange
Birne
Die Anwendung von set() auf eine Sequenz entfernt doppelte Elemente. Die Verwendung von sorted() in Kombination mit set() auf eine Sequenz ist eine gängige Methode, um die eindeutigen Elemente der Sequenz in sortierter Reihenfolge durchzugehen.
>>> basket = ['Apfel', 'Orange', 'Apfel', 'Birne', 'Orange', 'Banane']
>>> for f in sorted(set(basket)):
... print(f)
...
Apfel
Banane
Orange
Birne
Manchmal ist es verlockend, eine Liste zu ändern, während man sie in einer Schleife durchläuft; oft ist es jedoch einfacher und sicherer, stattdessen eine neue Liste zu erstellen.
>>> import math
>>> raw_data = [56.2, float('NaN'), 51.7, 55.3, 52.5, float('NaN'), 47.8]
>>> filtered_data = []
>>> for value in raw_data:
... if not math.isnan(value):
... filtered_data.append(value)
...
>>> filtered_data
[56,2, 51,7, 55,3, 52,5, 47,8]
5.7. Mehr zu den Bedingungen¶
Die in den Anweisungen while und if verwendeten Bedingungen können beliebige Operatoren enthalten, nicht nur Vergleichsoperatoren.
Die Vergleichsoperatoren in und not in sind Zugehörigkeitsprüfungen, die feststellen, ob ein Wert in einem Container enthalten ist (oder nicht). Die Operatoren is und is not vergleichen, ob zwei Objekte tatsächlich dasselbe Objekt sind. Alle Vergleichsoperatoren haben dieselbe Priorität, die niedriger ist als die aller numerischen Operatoren.
Vergleiche können verkettet werden. Beispielsweise prüft a < b == c “, ob a kleiner ist als b und ob darüber hinaus b gleich c ist.
Vergleiche können mithilfe der Booleschen Operatoren and und or kombiniert werden, und das Ergebnis eines Vergleichs (oder eines beliebigen anderen Booleschen Ausdrucks) kann mit not negiert werden. Diese haben eine niedrigere Priorität als Vergleichsoperatoren; unter ihnen hat not die höchste Priorität und or die niedrigste, sodass A and not B or C gleichbedeutend ist mit (A and (not B)) or C “. Wie immer können Klammern verwendet werden, um die gewünschte Zusammensetzung auszudrücken.
Die Booleschen Operatoren and und or sind sogenannte Kurzschluss-Operatoren: Ihre Argumente werden von links nach rechts ausgewertet, und die Auswertung wird beendet, sobald das Ergebnis feststeht. Sind beispielsweise A und C wahr, B jedoch falsch, so wertet A and B and C den Ausdruck C nicht aus. Wird ein Kurzschlussoperator als allgemeiner Wert und nicht als Boolescher Wert verwendet, ist der Rückgabewert das zuletzt ausgewertete Argument.
Es ist möglich, das Ergebnis eines Vergleichs oder eines anderen booleschen Ausdrucks einer Variablen zuzuweisen. Beispiel:
>>> string1, string2, string3 = '', 'Trondheim', 'Hammer Dance'
>>> non_null = string1 or string2 or string3
>>> non_null
'Trondheim'
Beachten Sie, dass in Python – anders als in C – Zuweisungen innerhalb von Ausdrücken explizit mit dem Walross-Operator := erfolgen müssen. Dadurch wird eine häufige Problemklasse vermieden, die in C-Programmen auftritt: die Eingabe von = in einem Ausdruck, obwohl eigentlich == gemeint war.
5.8. Vergleich von Sequenzen und anderen Typen¶
Sequenzobjekte können in der Regel mit anderen Objekten desselben Sequenztyps verglichen werden. Der Vergleich erfolgt nach lexikografischer Reihenfolge: Zunächst werden die ersten beiden Elemente verglichen; unterscheiden sie sich, bestimmt dies das Ergebnis des Vergleichs; sind sie gleich, werden die nächsten beiden Elemente verglichen und so weiter, bis eine der beiden Sequenzen erschöpft ist. Sind zwei zu vergleichende Elemente selbst Sequenzen desselben Typs, wird der lexikografische Vergleich rekursiv durchgeführt. Sind alle Elemente zweier Sequenzen gleich, gelten die Sequenzen als gleich. Ist eine Sequenz eine anfängliche Teilsequenz der anderen, ist die kürzere Sequenz die kleinere (geringere). Bei der lexikografischen Sortierung von Zeichenketten wird die Unicode-Codepunktnummer zur Sortierung einzelner Zeichen verwendet. Einige Beispiele für Vergleiche zwischen Sequenzen desselben Typs:
(1, 2, 3) < (1, 2, 4)
[1, 2, 3] < [1, 2, 4]
'ABC' < 'C' < 'Pascal' < 'Python'
(1, 2, 3, 4) < (1, 2, 4)
(1, 2) < (1, 2, -1)
(1, 2, 3) == (1,0, 2,0, 3,0)
(1, 2, ('aa', 'ab')) < (1, 2, ('abc', 'a'), 4)
Beachten Sie, dass der Vergleich von Objekten unterschiedlicher Typen mit < oder > zulässig ist, sofern die Objekte über entsprechende Vergleichsmethoden verfügen. Beispielsweise werden gemischte numerische Typen anhand ihres numerischen Werts verglichen, sodass 0 gleich 0,0 ist usw. Andernfalls liefert der Interpreter keine willkürliche Reihenfolge, sondern löst eine TypeError “-Ausnahme aus.
Fußnoten