zurück rauf weiter Englisch Index

Kapitel 8

Rohübersetzung -- bitte um Rückmeldungen über Fehler und Unklarheiten an Gregor Lingl

Listen

Eine Liste ist eine geordnete Menge von Werten, wobei jeder Wert mit einem Index angesprochen wird. Die Werte, die die Liste bilden, werden ihre Elemente genannt. Listen haben Ähnlichkeiten mit Strings, die geordnete Mengen von Zeichen sind. Die Elemente von Listen können dagegen beliebige Objekte sein. Listen und Strings     und andere Dinge, die sich wie geordnete Mengen verhalten     werden als Sequenzen bezeichnet.

8.1 Werte in Listen

Es gibt mehrere Möglichkeiten, eine neue Liste zu erzeugen. Die einfachste ist, ihre Elemente in eckige Klammern einzuschließen ([ and ]):

[10, 20, 30, 40]
["spam", "bungee", "swallow"]

Das erste Beispiel ist eine Liste von vier ganzen Zahlen. Das zweite ist eine Liste von drei Strings. Die Elemente einer Liste müssen nicht alle vom selben Typ sein. Die folgende Liste enthält einen String, eine Gleitkommazahl, eine Ganzzahl und (mirabile dictu) eine weitere Liste:

["hello", 2.0, 5, [10, 20]]

Eine Liste innerhalb einer anderen Liste wird als geschachtelte Liste bezeichnet.

Listen mit aufeinanderfolgenden Ganzzahlen sind so gebräuchlich, dass es in Python eine einfache Art gibt, sie zu erzeugen:

>>> range(1,5)
[1, 2, 3, 4]

Die range Funktion übernimmt zwei Argumente und gibt eine Liste zurück, die alle Ganzzahlen vom ersten Argument bis zum zweiten enthält, das erste eingeschlossen, das zweite aber nicht mehr!

Es gibt noch zwei andere Formen von range. Mit nur einem Argument erzeugt es eine Liste, die bei 0 beginnt:

>>> range(10)
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

Wenn ein drittes Argument übergeben wird, gibt dieses den Abstand zwischen aufeinanderfolgenden Werten an, was man die Schrittweite nennt. Dieses Beispiel erzeugt Werte von 1 (inklusive) bis 10 (exklusive) mit einer Schrittweite von 2:

>>> range(1, 10, 2)
[1, 3, 5, 7, 9]

Schließlich gibt es noch eine spezielle Liste, die keine Elemente enthält. Sie wird die leere Liste genannt und folgendermaßen notiert: [].

Mit all diesen Möglichkeiten, Listen zu erzeugen, wäre es enttäuschend, wenn wir Listen nicht als Werte in Variablen speichern oder sie als Argumente an Funktionen übergeben könnten. Natürlich geht das.

vocabulary = ["ameliorate", "castigate", "defenestrate"]
numbers = [17, 123]
empty = []
print vocabulary, numbers, empty
['ameliorate', 'castigate', 'defenestrate'] [17, 123] []

8.2 Zugriff auf die Listenelemente

Die Syntax für den Zugriff auf die Listenelemente ist dieselbe wie die Syntax für den Zugriff auf die Zeichen eines Strings     der Eckige-Klammer-Operator []). Der Ausdruck innerhalb der eckigen Klammern gibt den Index an. Man beachte, dass die Indizes bei 0 beginnen.

>>> print numbers[0]
17
>>> numbers[1] = 5
>>>

Der Eckige-Klammer-Operator kann an beliebigen Stellen in einem Ausdruck vorkommen. Wenn er auf der linken Seite einer Wertzuweisung erscheint, dann ändert diese das entsprechende Element in der Liste. Damit ist das "erste" Element von numbers, das zuvor 123 war, nun 5.

Jeder Ganzzahl-Ausdruck kann als Index verwendet werden:

>>> numbers[3-2]
5
>>> numbers[1.0]
TypeError: sequence index must be integer

Wenn man versucht ein Element zu lesen oder zu schreiben, das nicht existiert, erhält man einen Laufzeitfehler:

>>> numbers[2] = 5
IndexError: list assignment index out of range

Hat ein Index einen negativen Wert, dann wird er vom Ende der Liste zurückgezählt:

>>> numbers[-1]
5
>>> numbers[-2]
17
>>> numbers[-3]
IndexError: list index out of range

numbers[-1] ist das letzte Element der Liste, numbers[-2] ist das vorletzte, and numbers[-3]existiert (in unserem Beispiel) nicht.

Es ist gebräuchlich, Schleifenvariable als Listenindex zu verwenden.

horsemen = ["war", "famine", "pestilence", "death"]

i = 0
while i < 4:
  print horsemen[i]
  i = i + 1

Diese while Schleife zählt von 0 bis 4. Wenn die Schleifenvariable i gleich 4 ist, wird die Auswertung der Bedingung falsch ergeben und die Schleife abbrechen. Daher wird der Schleifenkörper nur für die Werte 0, 1, 2 und 3 von i ausgeführt.

Bei jedem Schleifendurchlauf wird die Variable i als ein Index für ein Listenelement benutzt, sodass das i.te Element ausgedruckt wird. Dieses Code-Muster wird als Listendurchlauf bezeichnet.

8.3 Die Länge einer Liste

Die Funktion len gibt die Länge einer Liste zurück. Es empfiehlt sich, diesen Wert als obere Grenze für Schleifen an Stelle von Konstanten zu verwenden. Auf diese Weise braucht man, wenn sich die Größe der Liste ändert, nicht ein ganzes Programm durchschauen um all die betroffenen Schleifen zu ändern; sie werden für jede Listengröße korrekt arbeiten:

horsemen = ["war", "famine", "pestilence", "death"]

i = 0
while i < len(horsemen):
  print horsemen[i]
  i = i + 1

Das letzte Mal wird der Schleifenkörper durchlaufen, wenn i gleich len(horseman) - 1 ist, und das ist ja auch der Index des letzten Listenelements. Wenn i gleich len(horseman) ist, wird die Bedingung nicht mehr erfüllt sein und der Schleifenkörper nicht mehr ausgeführt werden. Das ist gut so, denn len(horsemen) ist kein legaler Index mehr.

Obwohl eine Liste eine andere Liste enthalten kann, zählt eine solche geschachtelte Liste nur als ein einziges Element. Die Länge der folgenden Liste ist vier:

['spam!', 1, ['Brie', 'Roquefort', 'Pol le Veq'], [1, 2, 3]]

Übung: schreibe eine Schleife, die die obige Liste durchläuft und die Länge von jedem Element ausgibt. Was geschieht, wenn man eine Ganzzahl an len übergibt?

8.4 Zugehörigkeit zu einer Liste

in ist ein boole'scher Operator, der prüft ob ein Objekt Element von einer Sequenz ist. Wir haben ihn im Abschnitt 7.10 mit Strings verwendet, aber er funktioniert auch mit Listen und anderen Sequenzen:

>>> horsemen = ['war', 'famine', 'pestilence', 'death']
>>> 'pestilence' in horsemen
1
>>> 'debauchery' in horsemen
0

Weil "pestilence" ein Element der Liste horsemen ist, gibt der in - Operator wahr zurück. Weil "debauchery" nicht in der Liste ist, gibt in falsch zurück.

Wir können auch not in Kombination mit in verwenden, um zu prüfen, ob ein Element nicht zu einer Liste gehört:

>>> 'debauchery' not in horsemen
1

8.5 Listen und for Schleifen

Die for Schleife, die wir in Abschnitt 7.3 gesehen haben, funktioniert auch mit Listen. Die verallgemeinerte Syntax einer for Schleife ist:

for VARIABLE in LISTE:
  KÖRPER

Diese Anweisung ist gleichwertig mit:

i = 0
while i < len(LISTE):
  VARIABLE = LISTE[i]
  KÖRPER
  i = i + 1

Hier ist die vorige Schleife nocheinmal, diesmal geschrieben als for Schleife. Die for Schleife ist eine knappere Forumlierung, weil wir mit ihr die Schleifenvariable i eliminieren können.

for horseman in horsemen:
  print horseman

Liest sich fast wie Deutsch. Na ja, sagen wir     wie Englisch: "For (every) horseman in (the list of) horsemen, print (the name of the) horseman." Jeder Listen-Ausdruck kann in einer for Schleife verwendet werden.

for number in range(20):
  if number % 2 == 0:
    print  number

for fruit in ["banana", "apple", "quince"]:
  print "I like to eat " + fruit + "s!"

Das erste Beispiel gibt alle geraden Zahlen zwischen eins und zwanzig aus. Das zweite Beispiel drückt Begeisterung für verschiedene Früchte aus.

8.6 Operationen mit Listen

Der + Operator verkettet (auch) Listen:

>>> a = [1, 2, 3]
>>> b = [4, 5, 6]
>>> c = a + b
>>> print c
[1, 2, 3, 4, 5, 6]

In ähnlicher Weise vervielfacht der * Operator eine Liste die gegebene Anzahl von Malen.

>>> [0] * 4
[0, 0, 0, 0]
>>> [1, 2, 3] * 3
[1, 2, 3, 1, 2, 3, 1, 2, 3]

Das erste Beispiel vervielfacht [0] vier Mal. Das zweite Beispiel vervielfacht die Liste [1, 2, 3] drei Mal.

8.7 Listen Abschnitte

Die Abschnitt-Operationen, die wir in Abschnitt 7.4 gesehen haben, funktionieren auch für Listen:

>>> list = ['a', 'b', 'c', 'd', 'e', 'f']
>>> list[1:3]
['b', 'c']
>>> list[:4]
['a', 'b', 'c', 'd']
>>> list[3:]
['d', 'e', 'f']
>>> list[:]
['a', 'b', 'c', 'd', 'e', 'f']

8.8 Listen sind veränderbar

Im Unterschied zu Strings sind Listen veränderbar. Das bedeutet, dass wir ihre Elemente ändern können. Indem wir den Eckige-Klammer-Operator auf der linken Seite einer Wertzuweisung verwenden, können wir ein Element der Liste durch ein anderes ersetzen:

>>> fruit = ["banana", "apple", "quince"]
>>> fruit[0] = "pear"
>>> fruit[-1] = "orange"
>>> print fruit
['pear', 'apple', 'orange']

Mit dem Abschnitt-Operator können wir mehrere Elemente auf einmal ersetzen:

>>> list = ['a', 'b', 'c', 'd', 'e', 'f']
>>> list[1:3] = ['x', 'y']
>>> print list
['a', 'x', 'y', 'd', 'e', 'f']

Wir können auch Elemente aus einer Liste entfernen, indem wir ihnen die leere Liste zuweisen:

>>> list = ['a', 'b', 'c', 'd', 'e', 'f']
>>> list[1:3] = []
>>> print list
['a', 'd', 'e', 'f']

Und wir können Elemente zu einer Liste hinzufügen, indem wir sie in einen leeren Abschnitt an der gewünschten Stelle hineinpressen.

>>> list = ['a', 'd', 'f']
>>> list[1:1] = ['b', 'c']
>>> print list
['a', 'b', 'c', 'd', 'f']
>>> list[4:4] = ['e']
>>> print list
['a', 'b', 'c', 'd', 'e', 'f']

8.9 Elemente einer Liste löschen

Die Verwendung von Abschnitten zu Löschen von Listenelementen kann umständlich und daher fehleranfällig sein. Python stellt dafür eine besser lesbare Alternative zur Verfügung:

del entfernt ein Element von einer Liste:

>>> a = ['one', 'two', 'three']
>>> del a[1]
>>> a
['one', 'three']

Wie zu erwarten, verarbeitet del negative Indizes und verursacht Laufzeitfehler wenn der Index außerhalb des erlaubten Bereichs liegt.

Man kann auch Abschnitte als Index für del verwenden:

>>> list = ['a', 'b', 'c', 'd', 'e', 'f']
>>> del list[1:5]
>>> print list
['a', 'f']

Wie üblich wählen Abschnitte alle Elemente bis zum, aber ausschließlich des, letzten Index aus.

8.10 Objekte und Werte

Wenn man die folgenden Wertzuweisungen ausführt,

a = "banana"
b = "banana"

ist klar, dass a und b auf Strings mit den Zeichen banana verweisen werden. Aber man kann nicht sagen, ob sie auf denselben String zeigen.

Es gibt da zwei mögliche Zustände:

Im einen Fall verweisen a und b auf zwei verschiedene Dinge, die denselben Wert haben. Im zweiten Fall verweisen sie auf dasselbe Ding. Diese "Dinge" haben Namen -- sie werden Objekte genannt. Ein Objekt ist etwas, auf das eine Variable verweisen kann.

Jedes Objekt hat eine eindeutige Kennung, die man mit der id Funktion erhält. Indem man diese Kennungen von a und b ausgibt, kann man feststellen, ob sie auf dasselbe Objekt verweisen.

>>> id(a)
135044008
>>> id(b)
135044008

In der Tat bekommen wir dieselbe Kennung zwei Mal, was bedeutet, dass Python nur einen String erzeugt hat, und sowohl a als auch b darauf verweisen.

Interessanterweise verhalten sich Listen anders. Wenn man zwei Listen erzeugt, erhält man zwei verschieden Objekte:

>>> a = [1, 2, 3]
>>> b = [1, 2, 3]
>>> id(a)
135045528
>>> id(b)
135041704

Somit schaut das Zustandsdiagramm so aus:

a und b haben denselben Wert, verweisen aber nicht auf dasselbe Objekt.

8.11 Alias - Namen

Da also Variablen auf Objekte verweisen, geschieht es, dass wenn man eine Variable einer anderen zuweist, beide Variablen auf dasselbe Objekt verweisen:

>>> a = [1, 2, 3]
>>> b = a

In diesem Fall schaut das Zustandsdiagramm so aus:

Weil dieselbe Liste zwei verschiedene Namen hat, a und b, nennt man diese beiden Aliasnamen. Verändert man das Objekt, das zum einen gehört, ist der andere mitbetroffen:

>>> b[0] = 5
>>> print a
[5, 2, 3]

Obwohl dieses Verhalten nützlich sein kann, ist es manchmal unerwartet oder unerwünscht. Im allgemeinen ist es sicherer, Aliasnamen zu vermeiden, wenn man mit veränderbaren Objekten arbeitet. Natürlich gibt es für nicht veränderbare Objekte dieses Problem nicht. Deshalb kann sich der Python-Interpreter die Freiheit nehmen, Aliasnamen für Strings zu verwenden, wenn er dabei die Gelegenheit zu ökonomischerem Verhalten erkennt.

8.12 Klonen von Listen

Wenn wir eine Liste verändern möchten und auch ein Kopie der originalen Liste behalten möchten, müssen wir die Möglichkeit haben, eine Kopie der Liste zu erzeugen und nicht nur einen Verweis auf sie. Dieser Vorgang wird manchmal Klonen genannt, um die Zweideutigkeit des Wortes "kopieren" zu vermeiden.

Der einfachste Weg eine Liste zu klonen ist, den Abschnitt-Operator zu verwenden:

>>> a = [1, 2, 3]
>>> b = a[:]
>>> print b
[1, 2, 3]

Wenn man einen beliebigen Abschnitt von a erzeugt, wird eine neue Liste erzeugt. In diesem Fall besteht der Abschnitt eben aus der ganzen Liste.

Wir können nun unbedenklich Änderungen in b vornehmen, ohne uns um a kümmern zu müssen.

>>> b[0] = 5
>>> print a
[1, 2, 3]

Übung: Zeichne Zustandsdiagramme für a und b vor und nach dieser Änderung.

8.13 Listen als Parameter

Wenn man eine Liste als Argument übergibt, übergibt man in Wahrheit einen Verweis auf diese Liste, nicht eine Kopie der Liste. Zum Beispiel übernimmt die Funktion head eine Liste als Parameter und gibt deren erstes Element zurück:

def head(list):
  return list[0]

So wird sie verwendet:

>>> numbers = [1, 2, 3]
>>> head(numbers)
1

Der Parameter list und die Varible numbers sind Aliasnamen für dasselbe Objekt. Das Zustandsdiagramm sieht so aus:

Da das Listenobjekt von zwei Rahmen gemeinsam verwendet wird, haben wir es zwischen die beiden gezeichnet.

Wenn eine Funktion einen Listenparameter ändert, dann sieht auch der Aufrufer diese Änderung. Zum Beispiel entfernt deleteHead das erste Element von einer Liste:

def deleteHead(list):
  del list[0]

Und so wird deleteHead verwendet:

>>> numbers = [1, 2, 3]
>>> delete_head(numbers)
>>> print numbers
[2, 3]

Wenn eine Funktion eine Liste zurückgibt, dann gibt sie genau genommen einen Verweis auf die Liste zurück. Zum Beispiel gibt tail eine Liste zurück, die alle Elemente der gegebenen Liste bis auf das erste enthält.

def tail(list):
  return list[1:]

Und so wird tail verwendet:

>>> numbers = [1, 2, 3]
>>> rest = tail(numbers)
>>> print rest
[2, 3]

Weil der Rückgabewert mit dem Abschnitt-Operator erzeugt wird, ist er eine neue Liste. Die Erzeugung von Rest und jede folgende Änderung von Rest haben keine Auswirkung auf numbers.

8.14 Geschachtelte Listen

Eine geschachtelte Liste ist eine Liste, die als ein Element in einer anderen Liste auftritt. In der folgenden Liste ist das "dritte" Element eine geschachtelte Liste:

>>> list = ["hello", 2.0, 5, [10, 20]]

Wenn manlist[3] ausgibt, erhält man [10, 20]. Um auf eine Element aus einer geschachtelten Liste zuzugreifen, kann man in zwei Schritten vorgehen:

>>> elt = list[3]
>>> elt[0]
10

Man kann diese beiden Schritte aber auch kombinieren:

>>> list[3][1]
20

Eckige-Klammer-Operatoren werden von links nach rechts ausgewertet. Daher ergibt dieser Ausdruck das "dritte" Element von list und sucht das "erste" Element davon heraus.

8.15 Matrixes

Geschachtelte Liste werden oft verwendet um Matrizen darzustellen. Zum Beispiel kann

so dargestellt werden:

>>> matrix = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]

matrix ist eine Liste von drei Elementen, wobei jedes Element eine Zeile der Matrix ist. Wir können eine ganze Zeile der Matrix auf übliche Weise auswählen:

>>> matrix[1]
[4, 5, 6]

Oder wir können auf ein einzelnes Element der Matrix zugreifen, indem wir die Doppelindex-Form verwenden:

>>> matrix[1][1]
5

Der erste Index wählt die Zeile aus und der zweite Index wählt die Spalte aus. Obwohl diese Art Matrizen darzustellen gebräuchlich ist, ist sie nicht die einzige Möglichkeit. Eine leichte Variation davon ist, eine Liste von Spalten zu verwenden. Später werden wir eine grundlegender Alternative sehen, die ein "Dictionary" verwendet.

8.16 Strings und Listen

Die beiden nützlichsten Funktionen im string Modul betreffen Listen von Strings. Die split Funktion zerlegt einen String in eine Liste von Wörtern. Wenn nichts anderes angegeben wird, wird jede beliebige Anzahl von Whitespace-Zeichen als Wortgrenze genommen:

>>> import string
>>> song = "The rain in Spain..."
>>> string.split(song)
['The', 'rain', 'in', 'Spain...']

Ein optionales Argument, das als Begrenzer bezeichnet wird, kann verwendet werden um festzulegen, welche Zeichen als Wortgrenzen verwendet werden sollen. Das folgende Beispiel benützt den String ai als Begrenzer.

>>> string.split(song, 'ai')
['The r', 'n in Sp', 'n...']

Man beachte, dass der Begrenzer in der Liste nicht vorkommt.

Die join-Funktion ist die inverse zu split. Sie übernimmt eine Liste von Strings und verkettet deren Elemente mit Leerzeichen zwischen jedem Paar.

>>> list = ['The', 'rain', 'in', 'Spain...']
>>> string.join(list)
'The rain in Spain...'

Ebenso wie split übernimmt auch join einen optionalen Begrenzer, der zwischen die Elemente eingefügt wird:

>>> string.join(list, '_')
'The_rain_in_Spain...'

Übung: Beschreibe die Beziehung zwischen string.join(string.split(song)) und song. Sind sie für alle Strings gleich? Wann sind sie verschieden?

8.17 Glossar

Liste
Eine benannte Kollektion von Objekten, wobei jedes Objekt über einen Index angesprochen wird.
list
A named collection of objects, where each object is identified by an index.
Index
Eine Ganzzahl-Variable oder ein Ganzzahl-Wert, der ein Element einer Liste bezeichnet.
index
An integer variable or value that indicates an element of a list.
Element
Einer der Werte in einer Liste (oder in einer anderen Sequenz). Der Eckige-Klammer-Operator wählt Elemente der Liste aus.
element
One of the values in a list (or other sequence). The bracket operator selects elements of a list.
Sequenz
Einer der Datentypen, die aus einer geordneten Menge von Elementen bestehen, wobei jedes Element durch einen Index identifiziert wird.
sequence
Any of the data types that consist of an ordered set of elements, with each element identified by an index.
geschachtelte Liste
Eine Liste, die Element einer anderen Liste ist.
nested list
A list that is an element of another list.
Listen-Durchlauf
Der sequentielle Zugriff auf alle Elemente einer Liste.
list traversal
The sequential accessing of each element in a list.
Objekt
Ein Ding, auf das eine Variable verweisen kann.
object
A thing to which a variable can refer.
Alias-Namen
Verschieden Variablennamen, die Verweise auf dasselbe Objekt enthalten.
aliases
Multiple variables that contain references to the same object.
klonen
Ein neues Objekt erzeugen, das denselben Wert wie ein existierendes Objekt hat. Das Kopieren eines Verweises auf ein Objekt erzeugt einen Aliasnamen und klont das Objekt nicht.
clone
To create a new object that has the same value as an existing object. Copying a reference to an object creates an alias but doesn't clone the object.
Begrenzer
Ein Zeichen oder String, der dazu benutzt wird, festzulegen, wo ein String aufgespaltet werden soll.
delimiter
A character or string used to indicate where a string should be split.


zurück rauf weiter Englisch Index