5. Datenstrukturen

In diesem Kapitel werden einige Dinge, die du bereits kennengelernt hast, näher erläutert, und es werden zudem einige neue Aspekte hinzugefügt.

5.1. Mehr zum Thema Listen

The list data type has some more methods. Here are all of the methods of list objects:

list.append(x)

Add an item to the end of the list. Equivalent to a[len(a):] = [x].

list.extend(iterable)

Extend the list by appending all the items from the iterable. Equivalent to a[len(a):] = iterable.

list.insert(i, x)

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, und a.insert(len(a), x) entspricht a.append(x).

list.remove(x)

Remove the first item from the list whose value is equal to x. It raises a ValueError if there is no such item.

list.pop([i])

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 eine IndexError aus, wenn die Liste leer ist oder der Index außerhalb des Listenbereichs liegt.

list.clear()

Remove all items from the list. Equivalent to del a[:].

list.index(x[, start[, end]])

Return zero-based index in the list of the first item whose value is equal to x. Raises a ValueError if there is no such item.

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(x)

Return the number of times x appears in the list.

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()

Return a shallow copy of the list. Equivalent to a[:].

Ein Beispiel, das die meisten Methoden der Liste verwendet:

>>> fruits = ['orange', 'apple', 'pear', 'banana', 'kiwi', 'apple', 'banana']
>>> fruits.count('apple')
2
>>> fruits.count('tangerine')
0
>>> fruits.index('banana')
3
>>> fruits.index('banana', 4)  # Find next banana starting at position 4
6
>>> fruits.reverse()
>>> fruits
['banana', 'apple', 'kiwi', 'banana', 'pear', 'apple', 'orange']
>>> fruits.append('grape')
>>> fruits
['banana', 'apple', 'kiwi', 'banana', 'pear', 'apple', 'orange', 'grape']
>>> fruits.sort()
>>> fruits
['apple', 'apple', 'banana', 'banana', 'grape', 'kiwi', 'orange', 'pear']
>>> fruits.pop()
'pear'

Vielleicht ist dir 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.

Another thing you might notice is that not all data can be sorted or compared. For instance, [None, 'hello', 10] doesn’t sort because integers can’t be compared to strings and None can’t be compared to other types. Also, there are some types that don’t have a defined ordering relation. For example, 3+4j < 5+7j isn’t a valid comparison.

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, verwende append(). Um ein Element von der Spitze des Stapels abzurufen, verwende 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, verwende 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 arrives
>>> queue.append("Graham")          # Graham arrives
>>> queue.popleft()                 # The first to arrive now leaves
'Eric'
>>> queue.popleft()                 # The second to arrive now leaves
'John'
>>> queue                           # Remaining queue in order of arrival
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]

Beachte, 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:

squares = list(map(lambda x: x**2, range(10)))

oder, gleichbedeutend:

squares = [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) for x in [1,2,3] for y in [3,1,4] if 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)]

Beachte, 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]
>>> # create a new list with the values doubled
>>> [x*2 for x in vec]
[-8, -4, 0, 4, 8]
>>> # filter the list to exclude negative numbers
>>> [x for x in vec if x >= 0]
[0, 2, 4]
>>> # apply a function to all the elements
>>> [abs(x) for x in vec]
[4, 2, 0, 2, 4]
>>> # call a method on each element
>>> freshfruit = ['  banana', '  loganberry ', 'passion fruit  ']
>>> [weapon.strip() for weapon in freshfruit]
['banana', 'loganberry', 'passion fruit']
>>> # create a list of 2-tuples like (number, square)
>>> [(x, x**2) for x in range(6)]
[(0, 0), (1, 1), (2, 4), (3, 9), (4, 16), (5, 25)]
>>> # the tuple must be parenthesized, otherwise an error is raised
>>> [x, x**2 for x in range(6)]
  File "<stdin>", line 1
    [x, x**2 for x in range(6)]
     ^^^^^^^
SyntaxError: did you forget parentheses around the comprehension target?
>>> # flatten a list using a listcomp with two 'for'
>>> 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):
...     # the following 3 lines implement the nested listcomp
...     transposed_row = []
...     for row in matrix:
...         transposed_row.append(row[i])
...     transposed.append(transposed_row)
...
>>> transposed
[[1, 5, 9], [2, 6, 10], [3, 7, 11], [4, 8, 12]]

In der Praxis solltest du 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 findest du 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 Sequence Types — 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!')
>>> # Tuples may be nested:
... u = t, (1, 2, 3, 4, 5)
>>> u
((12345, 54321, 'hello!'), (1, 2, 3, 4, 5))
>>> # Tuples are immutable:
... t[0] = 88888
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: 'tuple' object does not support item assignment
>>> # but they can contain mutable objects:
... v = ([1, 2, 3], [3, 2, 1])
>>> v
([1, 2, 3], [3, 2, 1])

Wie du siehst, 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. Beachte, dass die Mehrfachzuweisung im Grunde nur eine Kombination aus Tupel-Packing und Sequenz-Unpacking ist.

5.4. Sets

Python also includes a data type for sets. A set is an unordered collection with no duplicate elements. Basic uses include membership testing and eliminating duplicate entries. Set objects also support mathematical operations like union, intersection, difference, and symmetric difference.

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.

Hier eine kurze Demonstration:

>>> basket = {'apple', 'orange', 'apple', 'pear', 'orange', 'banana'}
>>> print(basket)                      # show that duplicates have been removed
{'orange', 'banana', 'pear', 'apple'}
>>> 'orange' in basket                 # fast membership testing
True
>>> 'crabgrass' in basket
False

>>> # Demonstrate set operations on unique letters from two words
...
>>> a = set('abracadabra')
>>> b = set('alacazam')
>>> a                                  # unique letters in a
{'a', 'r', 'b', 'c', 'd'}
>>> a - b                              # letters in a but not in b
{'r', 'd', 'b'}
>>> a | b                              # letters in a or b or both
{'a', 'c', 'r', 'd', 'b', 'm', 'z', 'l'}
>>> a & b                              # letters in both a and b
{'a', 'c'}
>>> a ^ b                              # letters in a or b but not both
{'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 Types — 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.

The main operations on a dictionary are storing a value with some key and extracting the value given the key. It is also possible to delete a key:value pair with del. If you store using a key that is already in use, the old value associated with that key is forgotten. It is an error to extract a value using a non-existent key.

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 du die Liste sortiert haben möchtest, verwende stattdessen einfach sorted(d)). Um zu prüfen, ob ein einzelner Schlüssel im Wörterbuch enthalten ist, verwende 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
>>> 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': 'the pure', 'robin': 'the brave'}
>>> for k, v in knights.items():
...     print(k, v)
...
gallahad the pure
robin the brave

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.

>>> questions = ['name', 'quest', 'favorite color']
>>> answers = ['lancelot', 'the holy grail', 'blue']
>>> for q, a in zip(questions, answers):
...     print('What is your {0}?  It is {1}.'.format(q, a))
...
What is your name?  It is lancelot.
What is your quest?  It is the holy grail.
What is your favorite color?  It is blue.

Um eine Folge in umgekehrter Reihenfolge zu durchlaufen, gib zunächst die Folge in Vorwärtsrichtung an und rufe 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, verwende die Funktion sorted(), die eine neue sortierte Liste zurückgibt, während die Quelle unverändert bleibt.

>>> basket = ['apple', 'orange', 'apple', 'pear', 'orange', 'banana']
>>> for i in sorted(basket):
...     print(i)
...
apple
apple
banana
orange
orange
pear

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 = ['apple', 'orange', 'apple', 'pear', 'orange', 'banana']
>>> for f in sorted(set(basket)):
...     print(f)
...
apple
banana
orange
pear

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: Deine 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'

Beachte 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)

Beachte, 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