Listen

Eine Liste in Python ist ähnlich wie ein Array in Java oder C: eine geordnete Kollektion von Objekten. Anders als Listen in vielen anderen Sprachen können Python-Listen jedoch verschiedene Arten von Elementen enthalten; ein Listenelement kann ein beliebiges Python-Objekt sein, darunter Zeichenketten, Tupel, Listen, Dictionaries, Funktionen, Dateien und jede Art von Zahlen. Ihr erstellt eine Liste, indem ihr kein oder durch Komma getrennte Elemente in eckige Klammern einschließt, etwa so:

1[]
2[1]
3[1, "2.", 3.0, ["4a", "4b"], (5.1, 5.2)]

Tipp

Ich empfehle euch, nicht den in Python verfügbaren ctypes.Array-Typ zu verwenden, sondern, wenn es numerische Berechnungen erfordern, NumPy in Betracht ziehen, das in unserem Python für Data Science-Tutorial beschrieben ist.

Indizes

Elemente können aus einer Python-Liste extrahiert werden, indem eine Notation verwendet wird, die der Array-Indizierung in C ähnelt und mit 0 beginnt; die Frage nach Element 0 gibt das erste Element der Liste zurück, die Frage nach Element 1 gibt das zweite Element zurück u.s.w.. Hier sind ein paar Beispiele:

1>>> x = [1, "2.", 3.0, ["4a", "4b"], (5.1, 5.2)]
2>>> x[0]
3'1'
4>>> x[1]
5'2.'

Eine Liste kann von vorne oder hinten indiziert werden. Ihr könnt euch auch auf ein Teilsegment einer Liste beziehen, indem ihr die Slice-Notation verwendet:

 6>>> x[-1]
 7(5.1, 5.2)
 8>>> x[-2]
 9['4a', '4b']
10>>> x[1:-1]
11['2.', 3.0, ['4a', '4b']]
12>>> x[0:3]
13[1, '2.', 3.0]
14>>> x[:3]
15[1, '2.', 3.0]
16>>> x[-4:-1]
17['2.', 3.0, ['4a', '4b']]
18>>> x[-4:]
19['2.', 3.0, ['4a', '4b'], (5.1, 5.2)]
Zeilen 2 und 4

Index von vorne unter Verwendung positiver Indizes beginnend mit 0 als erstem Element.

Zeilen 6 und 8

Index von hinten unter Verwendung negativer Indizes beginnend mit -1 als letztem Element.

Zeilen 10 und 12

Slice mit [m:n], wobei m der inklusive Startpunkt und n der exklusive Endpunkt ist.

Zeilen 14, 16 und 18

Ein [:n]-Slice beginnt am Anfang und ein [m:]-Slice geht bis zum Ende einer Liste.

Slices erlauben auch eine stufenweise Auswahl zwischen den Start- und Endindizes. Der Standardwert für ein nicht spezifiziertes Stride ist 1, womit jedes Element aus einer Sequenz zwischen den Indizes genommen wird. Bei einem Stride von 2 wird jedes zweite Element übernommen usw.:

1>>> x[0:3:2]
2[1, [3.1, 3.2, 3.3]]
3>>> x[::2]
4[1, [3.1, 3.2, 3.3]]
5>>> x[1::2]
6['zweitens', (5.1, 5.2)]

Der Stride-Wert kann auch negativ sein. Ein -1-Stride bedeutet, dass von rechts nach links gezählt wird:

1>>> x[3:0:-2]
2[(5.1, 5.2), 'zweitens']
3>>> x[::-2]
4[(5.1, 5.2), 'zweitens']
5>>> x[::-1]
6[(5.1, 5.2), [3.1, 3.2, 3.3], 'zweitens', 1]
Zeile 1

Um eine negative Schrittweite zu verwenden, sollte das Start-Slice größer sein als das End-Slice.

Zeile 3

Die Ausnahme ist, wenn ihr die Start- und Endindizes weglasst.

Zeile 5

Ein Stride von -1 kehrt die Reihenfolge um.

Tipp

Zum Umkehren der Reihenfolge dürfte jedoch list.reverse() besser lesbar sein als ein Stride von -1, s.a. list.reverse().

Ändern von Listen

Ihr könnt diese Notation verwenden, um Elemente in einer Liste hinzuzufügen, zu entfernen und zu ersetzen oder um ein Element oder eine neue Liste zu erhalten, die ein Slice davon ist, z.B.:

 1>>> x = [1, "2.", 3.0, ["4a", "4b"], (5.1, 5.2)]
 2>>> x[1] = "zweitens"
 3>>> x
 4[1, 'zweitens', 3.0, ['4a', '4b'], (5.1, 5.2)]
 5>>> x[5:] = [6, 7]
 6>>> x
 7[1, 'zweitens', 3.0, ['4a', '4b'], (5.1, 5.2), 6, 7]
 8>>> x[:0] = [-1, 0]
 9>>> x
10[-1, 0, 1, 'zweitens', 3.0, ['4a', '4b'], (5.1, 5.2), 6, 7]
11>>> x[2:3] = []
12>>> x
13[-1, 0, 'zweitens', 3.0, ['4a', '4b'], (5.1, 5.2), 6, 7]
Zeile 2

ersetzt das zweite Element der Liste.

Zeile 5

fügt Elemente am Ende der Liste hinzu.

Zeile 8

fügt Elemente am Anfang der Liste hinzu.

Zeile 11

entfernt Elemente aus der Liste.

Einige Funktionen der Slice-Notation können auch mit speziellen Operationen ausgeführt werden, wodurch die Lesbarkeit des Codes verbessert wird:

1>>> x.reverse()
2>>> x
3[(5.1, 5.2), [3.1, 3.2, 3.3], 'zweitens', 1]

Darüberhinaus könnt ihr die eingebauten Funktionen (len(), max() und min()), einige Operatoren (in, not in, + und *), die del-Anweisung und die Listenmethoden (append, count, extend, index, insert, pop, remove, reverse, sort und sum) für Listen verwenden:

 1>>> len(x)
 24
 3>>> x[len(x) :] = [0, -1]
 4>>> x
 5[(5.1, 5.2), [3.1, 3.2, 3.3], 'zweitens', 1, 0, -1]
 6>>> x.append(-2)
 7>>> x
 8[(5.1, 5.2), [3.1, 3.2, 3.3], 'zweitens', 1, 0, -1, -2]
 9>>> y = [-3, -4, -5]
10>>> x.append(y)
11>>> x
12[(5.1, 5.2), [3.1, 3.2, 3.3], 'zweitens', 1, 0, -1, -2, [-3, -4, -5]]
13>>> x[7:8] = []
14>>> x
15[(5.1, 5.2), [3.1, 3.2, 3.3], 'zweitens', 1, 0, -1, -2]
16>>> x.extend(y)
17>>> x
18[(5.1, 5.2), [3.1, 3.2, 3.3], 'zweitens', 1, 0, -1, -2, -3, -4, -5]
19>>> x + [-6, -7]
20[(5.1, 5.2), [3.1, 3.2, 3.3], 'zweitens', 1, 0, -1, -2, -3, -4, -5, -6, -7]
21>>> x.reverse()
22>>> x
23[-5, -4, -3, -2, -1, 0, 1, 'zweitens', [3.1, 3.2, 3.3], (5.1, 5.2)]
Zeile 1

gibt die Anzahl der Listenelemente aus.

Zeile 3

hängt an das Ende der Liste eine neue Liste an.

Zeile 6

hängt mit append am Ende der Liste ein neues Element an.

Zeile 10

hängt mit append ans Ende der Liste nicht die Elemente der y-Liste an, sondern das Element y-Liste.

Zeile 16

hängt mit extend die Elemente der y-Liste an.

Zeile 19

Die Operatoren + und * erzeugen jeweils eine neue Liste, wobei die ursprüngliche Liste unverändert bleibt.

Zeile 21

Die Methoden einer Liste werden mit Hilfe der Attributschreibweise für die Liste selbst aufgerufen: LISTE.METHODE(ARGUMENTE).

Listenoperationen

Listen sortieren

Listen können mit Hilfe der eingebauten Python-Sortiermethode list.sort() sortiert werden:

>>> x = [5, 3, -3, 3.1, 0, 1]
>>> x.sort()
>>> x
[-3, 0, 1, 3, 3.1, 5]

Mit dieser Methode wird eine Sortierung an Ort und Stelle durchgeführt, d.h. die zu sortierende Liste wird geändert. Soll die ursprüngliche Liste unverändert bleiben, habt ihr zwei Möglichkeiten:

  1. ihr könnt die Built-in-Funktion sorted() verwenden, die später noch ausführlicher beschrieben wird.

  2. ihr könnt eine Kopie der Liste erstellen und die Kopie sortieren:

    >>> x = [5, 3, -3, 3.1, 0, 1]
    >>> y = x[:]
    >>> y.sort()
    >>> y
    [-3, 0, 1, 3, 3.1, 5]
    >>> x
    [5, 3, -3, 3.1, 0, 1]
    

Auch Zeichenketten und Listen von Listen können sortiert werden:

>>> hipy_list = ["Say", "hi", "to", "all", "Pythonistas", "!"]
>>> hipy_list.sort()
>>> hipy_list
['!', 'Pythonistas', 'Say', 'all', 'hi', 'to']
>>> ll = [[5.1, 5.2], [4.0, 5.0], [4.0, 3.0], [3.3, 3.2, 3.1]]
>>> ll.sort()
>>> ll
[[3.3, 3.2, 3.1], [4.0, 3.0], [4.0, 5.0], [5.1, 5.2]]

Beim Vergleich komplexer Objekte werden die Teillisten zuerst nach dem ersten Element und dann nach dem zweiten Element aufsteigend sortiert.

list.sort() kann auch in umgekehrter Reihenfolge sortieren mit reverse=True. Zudem kann auch eine eigene key-Funktion verwendet werden, um zu bestimmen, wie die Elemente einer Liste sortiert werden sollen.

Die Standard-key-Methode, die von list.sort() verwendet wird, erfordert jedoch, dass alle Elemente in der Liste von vergleichbarem Typ sind. In einer Liste, die sowohl Zahlen als auch Zeichenketten enthält, wird daher eine Exception ausgelöst:

>>> x
[-5, -4, -3, -2, -1, 0, 1, 'zweitens', [3.1, 3.2, 3.3], (5.1, 5.2)]
>>> x.sort()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: '<' not supported between instances of 'str' and 'int'

Benutzerdefinierte Sortierung

Bemerkung

Für eine benutzerdefinierte Sortierung müsst ihr Funktionen definieren können. Und auch die Verarbeitung von Zeichenketten wird später noch ausführlicher behandelt.

Üblicherweise sortiert Python Wörter lexikografisch – Großbuchstaben vor Kleinbuchstaben. Wir möchten jedoch stattdessen eine Liste von Wörtern nach der Anzahl der Zeichen in jedem Wort aufsteigend sortieren:

>>> def ascending_number_chars(string):
...     return len(string)
...
>>> hipy_list = ["Say", "hi", "to", "all", "Pythonistas", "!"]
>>> new_list = hipy_list[:]
>>> hipy_list.sort()
>>> hipy_list
['!', 'Pythonistas', 'Say', 'all', 'hi', 'to']
>>> new_list.sort(key=ascending_number_chars)
>>> new_list
['!', 'hi', 'to', 'Say', 'all', 'Pythonistas']

Die Funktion sorted

Listen haben eine eingebaute Methode, um sich selbst zu sortieren list.sort(). Andere Iterables in Python, wie z.B. die Schlüssel von Dictionaries, haben jedoch keine Sortiermethode. Python bietet hierfür jedoch die eingebaute Funktion sorted() an, die eine sortierte Liste aus einer beliebigen Iterables zurückgibt. sorted() verwendet die gleichen Parameter key und reverse wie die Methode list.sort():

>>> x
[5, 3, -3, 3.1, 0, 1]
>>> y = sorted(x)
>>> y
[-3, 0, 1, 3, 3.1, 5]
>>> z = sorted(x, reverse=True)
>>> z
[5, 3.1, 3, 1, 0, -3]

Listenzugehörigkeit

Mit den in und not in-Operatoren, die einen booleschen Wert zurückgeben, lässt sich leicht prüfen, ob ein Wert in einer Liste enthalten ist.

Listenverkettung

Der +-Operator kann verwendet werden um eine Liste aus zwei bestehenden Listen zu erstellen, wobei die Ausgangslisten unverändert bleiben:

>>> x = [3, -3, 0, 1]
>>> y = [3.1]
>>> z = x + y
>>> z
[3, -3, 0, 1, 3.1]

Listeninitialisierung

Ihr könnt den *-Operator verwenden, um eine Liste bestimmter Größe und bestimmter Werte zu erzeugen. Dies ist eine gängige Methode, um mit Listen zu arbeiten, deren Größe im Voraus bekannt ist und die dann auch keinen Memory-Reallocation-Overhead verursacht. Daher solltet ihr dies in solchen Fällen append vorziehen, um die Liste zu Beginn des Programms zu vergrößern:

>>> x = [None] * 4
>>> x
[None, None, None, None]

Der Operator für list-Multiplikationen * wiederholt das Kopieren der Elemente einer Liste die angegebene Zahl und fügt alle Kopien zu einer neuen Liste zusammen. Dabei wird üblicherweise eine Liste mit einer einzelnen Instanz von None für die Listenmultiplikation verwendet, aber die Liste kann alles sein:

>>> initial_list = [[1, 2, 3, 4]]
>>> arr = initial_list * 4
>>> arr
[[1, 2, 3, 4], [1, 2, 3, 4], [1, 2, 3, 4], [1, 2, 3, 4]]

Minimum oder Maximum einer Liste

Ihr könnt max() und min() verwenden, um das größte und kleinste Element einer Liste zu finden. Wahrscheinlich werdet ihr max() und min() vor allem bei numerischen Listen verwenden, aber ihr könnt sie auch bei Listen mit beliebigen Elementen einsetzen; wenn der Vergleich dieser Typen jedoch keinen Sinn ergibt, führt dies zu einem Fehler:

>>> x = [5, 3, -3, 3.1, 0, 1]
>>> max(x)
5
>>> hipy_list = ["Say", "hi", "to", "all", "Pythonistas", "!"]
>>> max(hipy_list)
'to'
>>> max(x + hipy_list)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: '>' not supported between instances of 'str' and 'int'

Beim Vergleich komplexer Objekte werden die Teillisten zuerst nach dem ersten Element und dann nach dem zweiten Element u.s.w. /und so weiter) analysiert.

>>> ll = [[1.0, 1.1], [1.0, 1.1, 1.2], [0.9, 1.3]]
>>> max(ll)
[1.0, 1.1, 1.2]

Suche in einer Liste

Wenn ihr wissen wollt, wo in einer Liste ein Wert zu finden ist, könnt ihr Sie die index-Methode verwenden. Sie durchsucht eine Liste nach einem Listenelement mit einem bestimmten Wert, und gibt die Position dieses Listenelements zurück:

 1>>> x = [5, 3, 3.0, -3, 3.1, 0, 1]
 2>>> x.index(3)
 31
 4>>> x.index(3.0)
 51
 6>>> x.index(5.0)
 70
 8>>> x.index(6)
 9Traceback (most recent call last):
10  File "<stdin>", line 1, in <module>
11ValueError: 6 is not in list
Zeile 8–11

Der Versuch, die Position eines Elements zu finden, das nicht in der Liste vorhanden ist, führt zu einem Fehler. Dieser kann durch Testen der Liste mit den in oder not-in-Listenoperatoren vor der Verwendung von index vermieden werden.

Übereinstimmungen in Listen

count durchsucht ebenfalls eine Liste nach einem bestimmten Wert, gibt aber die Anzahl der Vorkommen in der Liste zurück und nicht die Position:

>>> x = [5, 3, 3.0, -3, 3.1, 0, 1]
>>> x.count(3)
2
>>> x.count(5)
1
>>> x.count(6)
0

Verschachtelte Listen und deepcopy

Listen können verschachtelt werden, z.B. für die Darstellung zweidimensionaler Matrizen. Auf die Elemente dieser Matrizen kann mit Hilfe von zweidimensionalen Indizes verwiesen werden:

>>> ll = [[5.1, 5.2], [4.0, 5.0], [4.0, 3.0], [3.3, 3.2]]
>>> ll[0]
[5.1, 5.2]
>>> ll[0][1]
5.2

Dieser Mechanismus lässt sich wie erwartet auf mehr Dimensionen übertragen:

>>> sub = [0]
>>> sup = [sub, 1]
>>> sup
[[0], 1]
>>> sub[0] = 1
>>> sup
[[1], 1]
>>> sup[0][0] = 2
>>> sub
[2]
>>> sup
[[2], 1]

Wenn aber sub auf eine andere Liste gesetzt wird, ist die Verbindung zwischen sub und sup unterbrochen:

>>> sub = [3]
>>> sup
[[2], 1]

Ihr könnt eine Kopie einer Liste erhalten, indem ihr ein vollständiges Slice (also x[:] erzeugt) oder + oder * verwendet (z.B. x + [] oder x * 1). Alle drei erzeugen eine so genannte flache Kopie der Liste, was wahrscheinlich in den meisten Fällen das Gewünschte ist. Wenn eure Liste jedoch andere Listen enthält, die in ihr verschachtelt sind, möchtet ihr vielleicht eine tiefe Kopie erstellen. Dies könnt ihr mit der Funktion copy.deepcopy() des copy-Moduls tun:

>>> shallow = sup[:]
>>> shallow
[[2], 1]

Die shallow-Kopie kopiert nicht die Elemente der Liste sondern verweist nur auf die ursprünglichen Elemente. Die Änderung eines dieser Elemente wirkt sich sowohl auf shallow wie auch auf sup aus:

>>> shallow[1] = 2
>>> shallow
[[2], 2]
>>> sup
[[2], 1]
>>> shallow[0][0] = 0
>>> sup
[[0], 1]

deepcopy ist jedoch unabhängig von der Originalliste, und keine Änderung an ihr hat Auswirkungen auf die Originalliste:

>>> import copy
>>> deep = copy.deepcopy(sup)
>>> deep
[[0], 1]
>>> deep[0][0] = 1
>>> deep
[[1], 1]
>>> sup
[[0], 1]

Checks

  • Was gibt len() für jeden der folgenden Fälle zurück:

    • [3]

    • []

    • [[1, [2, 3], 4], "5 6"]

  • Wie würdet ihr mit len() und Slices die zweite Hälfte einer Liste ermitteln, wenn ihr nicht wisst, wie groß sie ist?

  • Wie könntet ihr die letzten zwei Einträge einer Liste an den Anfang verschieben, ohne die Reihenfolge der beiden zu ändern?

  • Welcher der folgenden Fälle löst eine Exception aus?

    • min(["1", "2", "3"])

    • max([1, 2, "3"])

    • [1,2,3].count("1")

  • Wenn ihr eine Liste l habt, wie könnt ihr daraus einen bestimmten Wert i entfernen?

  • Wenn ihr eine verschachtelte Liste ll habt, wie könnt ihr eine Kopie nll dieser Liste erhalten, in der ihr die Elemente ändern könnt, ohne den Inhalt von ll zu verändern?

  • Stellt sicher, dass das Objekt my_collection eine Liste ist, bevor ihr versucht, daran Daten anzuhängen.