lehrkraefte:snr:informatik:glf22:python:listen

Listen

Eine Liste ist eine Datenstruktur, die eine geordnete endliche Folge von Elementen enthält; dabei dürfen Elemente mehrfach vorkommen.

Ein Beispiel ist die Liste aller Schüler und Schülerinnen einer Klasse (meist ist diese alphabetisch geordnet).

In der Informatik beginnt man beim Durchnummerieren der Elemente einer Liste bei 0 und nicht bei 1 (wie im normalen Leben).

Gib die folgenden Befehle in der Python-Shell ein, jeweils gefolgt von Enter. Versuche dabei zu verstehen, was passiert.

Hinweis: Mit den Pfeiltasten und bekommt man der Python-Shell (und fast jeder anderen Shell) die zuvor eingegebenen Befehle. Damit kann man sich viel Schreibarbeit sparen. Man verwende auch die Tabulatortaste Tab zur “string completion”: Die bereits getätigte Eingabe wird sinnvoll ergänzt, falls möglich.

schuelerliste = ["Anna", "Berta", "Charly", "Daniel", "Emil", "Berta", "Ida"]
len(schuelerliste)
schuelerliste
schuelerliste[0]
schuelerliste[4]
schuelerliste[-2]
schuelerliste[-1]
"Peter" in schuelerliste
"Daniel" in schuelerliste

Damit du siehst, dass all diese Befehle die Liste nicht verändert haben, lass diese noch einmal ausgeben mit:

schuelerliste

Lösung: Was du gelernt haben solltest …

Lösung: Was du gelernt haben solltest …

… wird in der folgenden Infobox erklärt.

Definition von Listen durch aufzählende Schreibweise

In Python kann man Listen durch aufzählende Schreibweise definieren, z. B. ist

["Anna", "Berta", "Charly", "Daniel", "Emil", "Berta", "Ida"]

eine Liste. Diese haben wir oben in der Variablen schuelerliste gespeichert.

Genauso kann man Listen von Zahlen definieren, etwa durch

[42, 3, 36, 1, 2, 3]

Listen dürfen sogar Zahlen und Zeichenketten (also verschiedene Datentypen wie integers, floats, strings1)) gleichzeitig enthalten:

["Anna", "Hello World", 42, 3.14159]

Länge einer Liste

Die Anzahl der Elemente einer Liste erhält man mit der Funktion len (als Abkürzung für length).

  • Dies war der Befehl len(schuelerliste) in der Aufgabe oben.

Zugriff auf Listenelemente

Auf die Elemente einer Liste kann man mit Hilfe der Syntax <Name der Liste>[<Index>] zugreifen.

Achtung, die Nummerierung der Listenelemente beginnt bei Null!

  • schuelerliste[0] liefert den nullten (in Informatik-Zählweise bzw. den ersten in normaler Zählweise) Eintrag der obigen Liste, also “Anna”.
  • schuelerliste[2] liefert den zweiten Eintrag, also “Charly”.

Ist der Index negativ, so wird “von hinten gezählt”.

  • schuelerliste[-1] liefert den letzten Eintrag (= den ersten Eintrag von hinten), also “Ida”.
  • schuelerliste[-3] liefert den drittletzten Eintrag, also “Emil”.

Test, ob etwas in einer Liste auftaucht

Mit dem Schlüsselwort in kann man testen, ob ein Element in einer Liste auftaucht:

  • “Peter” in schuelerliste liefert den booleschen Wert False.
  • “Daniel” in schuelerliste liefert den booleschen Wert True.

Wenn wir im Folgenden vom nullten, ersten, zweiten, …, $x$-ten Element einer Liste sprechen, verwenden wir die Nummerierungskonvention der Informatik (und meinen das Element, das man im normalen Leben als erstes, zweites, drittes, …, $(x+1)$-tes Element bezeichnen würde).

Speichere das folgende Programm ab und lass es in Visual Studio Code (oder anderweitig) laufen. Was sollst du dabei lernen?

schuelerliste = ["Anna", "Berta", "Charly", "Daniel", "Emil", "Berta", "Ida"]
for s in schuelerliste:
    print(s)

Lösung

Lösung

Bisher haben wir nur for-loops kennengelernt, bei denen die Laufvariable alle Elemente eines Bereichs von Zahlen nacheinander abklappert (etwa per for s in range(7):).

Das obige Python-Programm illustriert, wie man eine Schleife programmiert, deren Laufvariable nacheinander alle Elemente der Liste als Wert annimmt.

Hier noch zwei Alternativen, die dasselbe wie der obige Code bewirken, aber etwas weniger elegant sind:

  • Mit einer for-Schleife:
    schuelerliste = ["Anna", "Berta", "Charly", "Daniel", "Emil", "Berta", "Ida"]
    for index in range(len(schuelerliste)):
        print(schuelerliste[index])
  • Mit einer while-Schleife:
    schuelerliste = ["Anna", "Berta", "Charly", "Daniel", "Emil", "Berta", "Ida"]
    index = 0 
    while index < len(schuelerliste):
        print(schuelerliste[index])
        index = index + 1

Wähle eines der drei gerade betrachteten Programme (for-loop über Liste, klassische for-loop oder while-loop). Ergänze die Liste schuelerliste um weitere fünf Namen und modifiziere das Programm so, dass nur jeder dritte Name aus der Liste ausgegeben wird. Ausserdem soll bei jedem Namen zusätzlich seine Nummer in der Liste ausgegeben werden.

Hinweis

Hinweis

Verwende das Rechenzeichen %, das den Rest einer ganzzahligen Division liefert.

Hinweis, falls du das Programm mit der for-loop über die Liste gewählt hast

Hinweis, falls du das Programm mit der for-loop über die Liste gewählt hast

Du musst eine zusätzliche Variable index verwenden, die angibt, das wievielte Element der Liste gerade betrachtet wird.


Lösungen zu ergänzen!

Lösung mit for-loop über Zahlenbereich

Lösung mit for-loop über Zahlenbereich

Lösung mit while-loop

Lösung mit while-loop

Lösung mit loop über Liste

Lösung mit loop über Liste

Bonusmaterial: Elegantere Lösung mit loop über die Liste

Bonusmaterial: Elegantere Lösung mit loop über die Liste

Erweitere das folgende Python-Programm so, dass dem Benutzer die Fragen aus der Liste fragen gestellt werden und die entsprechenden Antworten aus der Liste korrekteAntworten als korrekte Antworten akzeptiert werden (und kompromisslos alles andere als falsch gewertet wird).

Verwende dabei eine for-Schleife über die Fragenliste!

Erweitere den Quiz um mindestens eine Frage deiner Wahl.

fragen = ["Wie hoch ist der Säntis?", "Bei welcher Ortschaft entsteht die Sitter?", "Wie tief ist der Bodensee an seiner tiefsten Stelle?"]
korrekteAntworten = ["2502 Meter", "Weissbad", "251 Meter"]

Gib die folgenden Befehle in der Python-Shell ein, jeweils gefolgt von Enter, und versuche dabei zu verstehen, was passiert.

liste = ["Anna", "Berta", "Charly", "Daniel", "Emil", "Berta", "Ida"]
liste
liste[2] = "Carl"
liste
liste = liste + ["Peter", "Paul", "Reto", "Flurina"] 
liste

Beachte bei den folgenden Befehlen die neue Syntax: Unmittelbar nach einer Liste folgt ein Punkt und danach ein Befehl, der in Klammern gewisse Argumente entgegennimmt.

liste.append("Friedrich")
liste
liste.append("Marie")
liste

Lass dir ähnlich wie oben nach jedem der folgenden Befehle den aktuellen Zustand der Liste anzeigen (durch Eingabe von liste)!

liste.pop()
liste.pop(3)
liste.insert(2, "Gustav")
liste.count("Berta")
liste.index("Berta")
liste.remove("Berta")
liste.reverse()
liste.sort()

Lösung: Was du gelernt haben solltest …

Lösung: Was du gelernt haben solltest …

… und etwas mehr wird in der folgenden Infobox erklärt.

Wenn man beispielsweise das zweite Element einer Liste ändern will, geht dies per schuelerliste[2] = “Carl”.

Ähnlich wie beim “Addieren von Strings” (z. B. “Hello ” + “World!”) kann man Listen addieren: Das Ergebnis ist die “zusammengefügte” Liste.

Nun zu den Befehlen, die man per <Listennahme>.<Befehl>(<Argument(e)>) aufruft:

  • append(<Element>): Das Argument <Element> wird als letztes Element an die Liste angefügt.
  • pop(): Das letzte Element der Liste wird gelöscht und zurückgeliefert. Beachte, dass hier kein Argument übergeben wird. Trotzdem sind Klammern nötig.

Mit den beiden gerade erklärten Befehlen kann man eine Liste wie einen Stapel (englisch stack) von Akten verwenden: Neue Akten kommen per append oben auf den Stapel (bzw. in horizontaler Listenschreibweise “rechts” an die Liste dran); mit pop() holt man sich die oberste Akte vom Stapel.

  • pop(<Position>): Das Element an Position <Position> wird gelöscht und zurückgeliefert.
  • insert(<Position>, <Element>): An Position <Position> wird das Element <Element> eingefügt (die Elemente dahinter rücken eine Position weiter).
  • count(<Argument>): Zählt, wie oft das <Argument> in der Liste auftaucht.
  • index(<Argument>): Die erste Position, an der <Argument> in der Liste auftaucht, wird zurückgeliefert. (Fehler, falls <Argument> nicht in der Liste vorkommt.)
  • remove(<Argument>): Das erste in der Liste auftretende <Argument> wird aus der Liste entfernt. (Fehler, falls es nicht vorkommt.)
  • reverse(): Dreht die Liste um: Das letzte Element wird das erste etc.
  • sort(): Sortiert die Liste.

Beachte: Einige dieser Befehle verändern bisweilen die Liste (wie insert), einige verändern die Liste und liefern einen Rückgabewert (wie pop), einige verändern die die Liste nicht, liefern aber einen Wert (wie index).

In der Python-Shell:

  1. Definiere eine Liste zahlen aus mindestens 10 Zahlen.
  2. Gib das 4. Element der Liste aus.
  3. Entferne das letzte Element aus der Liste und gib es aus.
  4. Gib die Liste aus (dies kannst du im Folgenden immer mal wieder als Test machen).
  5. Füge die Zahlen 17, 42, 15, 42 und 91 hinten an die Liste an.
  6. Lösche das dritte Element aus der Liste und gib es aus.
  7. Gib aus, wie oft die Zahl 42 in der Liste vorkommt.
  8. Gib aus, an welcher Position die Zahl 42 (zum ersten Mal) in der Liste vorkommt.
  9. Lösche die Zahl 42 aus der Liste.
  10. Füge an zweiter Position die Zahl 1000 in die Liste ein.

Screenshot meiner Lösung

Screenshot meiner Lösung

Schreibe ein Python-Programm, das vom Benutzer so lange Zahlen einliest und diese in einer Liste speichert, bis dieser “q” (wie quit) eingibt. In diesem Fall soll die gesamte Liste und die Summe der Listenelemente ausgegeben werden.

Hinweis:

Hinweis:

Ohne while-loop und if-Abfrage wird das kaum gehen. Verwende eine boolesche Variable quitEingegeben = False, die steuert, ob die while-Schleife ausgeführt wird.

Wenn man eine Liste aufeinanderfolgender ganzer Zahlen haben möchte, bekommt man diese mit Befehlen wie

list(range(10))

und

list(range(5,15))

Du kannst dies gerne in der Python-Shell ausprobieren. (Eventuell erinnerst du dich, dass ich das im Video zu for-loops bereits erklärt habe - damals war der Begriff der Liste noch unbekannt.)

Stell dir vor, du sollst eine Liste aller Quadratzahlen bis zu einer gewissen, variabel definierten Obergrenze erzeugen und diese Liste dann ausgeben.

Mit dem bisherigen Wissen würde man wohl wie folgt vorgehen: Starte mit der “leeren Liste” quadratzahlen = [] und hänge in einer for-loop geeignete Quadratzahlen an diese Liste an. Gib die Liste dann aus.

Überlege dir im Kopf, wie man das programmieren würde, und schau dir dann den folgenden Lösungsvorschlag an!

Lösungsvorschlag

Lösungsvorschlag

obergrenze = 100
quadratzahlen = []
for i in range(1, obergrenze + 1):
    quadratzahlen.append(i * i)
print(l)

Netterweise kann man die Liste quadratzahlen (sagen wir bis $100^2$) in Python mit der folgenden Syntax viel einfacher erzeugen:

Elegante Form der Listenerzeugung mit “interner for-Schleife”

Elegante Form der Listenerzeugung mit “interner for-Schleife”

quadratzahlen = [x * x for x in range(1, 101)]

Bemerkung für Mathematiker

Bemerkung für Mathematiker

Diese “Listenerzeugung mit interner for-loop” ist der mathematischen Notation $\{x^2 \mid x \in \{1, \dots, 100\}\}$ nachempfunden. Sprechweise: “Die Menge aller $x^2$ für $x$ in der Menge der Zahlen von 1 bis 100.”

(1) Teste die folgenden Befehle in der Python-Shell und versuche die Ausgabe zu verstehen:

[x ** 3 for x in range(1, 21)]
["Hallo " + name + "!" for name in ["Anna", "Berta", "Charly", "Emil"]]

Erzeuge in ähnlicher Weise in der Python-Shell:

(2) Eine Liste aus 20 Elementen, deren $i$-tes Element die $i$-fache Hintereinanderschreibung des Worts “la” ist (das dritte Element ist beispielsweise der String “lalala”). (Hinweis: Rechnen mit Strings)

(3) Die Liste aller (ganzen) Zahlen von 5 bis 20.

(4) Die Liste aller Zahlen von 7 bis 97 “mit Schrittweite 10”, also die Liste [7, 17, 27, 37, 47, 57, 67, 77, 87, 96].

(5) Eine Liste, die 20 Mal den booleschen Wert True enthält. (Anwendungsbeispiel: Anwesenheitsliste)

Lösungsvorschläge

Lösungsvorschläge

(2)

[i * "la" for i in range(20)]

(3) Statt des oben erklärten list(range(5, 21)) geht neu auch

[i for i in range(5, 21)]

(4)

[7 + 10 * i for i in range(10)]

(5)

[True for i in range(20)]

Die folgenden Befehle illustrieren, wie man Teillisten einer Liste bekommt (ohnd die ursprüngliche Liste zu verändern). Gib sie in der Python-Shell ein und versuche zu verstehen, was passiert!

liste = ["Anna", "Berta", "Charly", "Daniel", "Emil", "Berta", "Ida"]
liste[1:4]

Auf was wird der erste Parameter gesetzt, wenn man ihn weglässt?

liste[:4] 

Auf was wird der zweite Parameter gesetzt, wenn man ihn weglässt?

liste[2:] 

Überzeuge dich, dass die ursprüngliche Liste bei all diesen Befehlen nicht verändert wurde!

liste

Bonusmaterial

Schreibe ein Programm, das mit Hilfe des Siebs des Eratosthenes eine Liste aller Primzahlen bis zu einer gegebenen Grenze n ausgibt, etwa n = 1000000.

Hinweis

Hinweis

Das Programm geht beispielsweise so los:

n = 1000000
prim = [True for i in range(n + 1)]
prim[0] = False
prim[1] = False

Solange prim[x] wahr ist, ist x ein Kandidat für eine Primzahl. Wenn x beim Sieb des Eratosthenes gestrichen wird, setzen wir prim[x] = False.

Die Schlange bei Snake bzw. genauer die Liste ihrer Koordinaten ist ein perfektes Beispiel für eine Liste, die modifiziert wird: Vorne wird etwas hinzugefügt, hinten etwas entfernt… Beim Apfel-Essen wird nur etwas hinzugefügt.

Snake weiterprogrammieren!

(Verwende etwa die Musterlösung zum “Box-Steuer-Programm”. Verwende zwei Listen, eine für x-Koordinaten und eine für y-Koordinaten der Schlange. Verwende append und pop. Alternative: Verwende eine Liste, deren Elemente “2-Tupel” alias Listen mit zwei Einträgen sind (oder gar echte Tupel oder gar dictionaries).)

Teste weiter in der Python-Shell:

liste = ["Anna", "Berta", "Charly", "Daniel", "Emil", "Berta", "Ida"]

Was passiert, wenn man beide Parameter weglässt? (Dies wirkt hier überflüssig, kann jedoch zum Kopieren von Listen verwendet werden, wo man etwas aufpassen muss, wie später erklärt werden mag.)

liste[:]

Was passiert bei negativen Parametern? (Hilfe/Erinnerung: liste[-1] liefert das letzte Element der Liste.)

liste[3:-1]
liste[-4:-1]

Auch ein dritter Parameter ist erlaubt (als Schrittweite).

liste[0:5:2]

Auch negative Schrittweiten sind erlaubt.

liste[6:2:-1]

Um die Reihenfolge der Elemente einer Liste umzukehren, ist die folgende Syntax erlaubt. (Die weggelassenen Parameter werden bei negativer Schrittweise anders interpretiert als oben bei positiver Schrittweite.)

liste[::-1] 

Oben hast du ein Programm geschrieben, dass nur jeden zweiten Namen aus einer Liste von Namen ausgibt. Das geht mit dem neuen Wissen deutlich kürzer! Wie?

Achtung beim Kopieren von Listen: Da können Dinge passieren, die man auf den ersten Blick nicht erwartet!

Hier ist der Link zu meinen alten Erklärungen dazu (wird eventuell bald verbessert): https://fginfo.ksbg.ch/dokuwiki/doku.php?id=lehrkraefte:snr:informatik:python:listen#listen_sind_mutabel_veraenderlich_englisch_mutable

Vieles, was du für Listen gelernt hast, geht analog für Strings. Teste die folgenden Beispiele und sei selbst kreativ im Ausprobieren!

s = "Sehr geehrte Damen und Herren!"
s
s[0]
s[5:12]
s.index("D")
s.count("e")
s

Auch kannst du eine for-Schleife über die Einzelzeichen eines Strings laufen lassen. Dies kannst du auch in der Python-Shell testen, da man dort auch mehrzeilige Befehle eingeben darf (beachte die Einrückung und dass du nach der Eingabe von print(z) zweimal Enter drücken musst).

for z in "Hallo":
    print(z)

Zusatzinformationen

Du kannst dir eine Liste der “Attribute” des Strings s mit dem folgenden Befehl anzeigen lassen:

dir(s)

Die in dieser Liste mit einem Unterstrich anfangenden Attribute sind “privat” und sollten nicht verwendet werden. Um die anderen anzeigen zu lassen, gib das Folgende ein. (Es handelt sich um eine Erweiterung der obigen Notation für “Listen-Erzeugung mit interner for-Schleife” um eine if-Bedingung: Nur diejenigen Elemente werden in die Liste aufgenommen, die die angegebene Bedingung erfüllen.)

[befehl for befehl in dir(s) if befehl[0] != "_"]

In dieser Liste findest du etwa den Befehl upper. Teste ihn mit

s.upper()
saeulendiagramm.py
from matplotlib import pyplot
 
xWerte = [i for i in range(-10, 30)]
yWerte = [(x-3)*(x+2)*(x-25) for x in xWerte]
pyplot.bar(xWerte, yWerte, color='blue')
pyplot.show()
graph.py
from matplotlib import pyplot
 
xWerte = [i for i in range(-10, 30)]
yWerte = [(x-3)*(x+2)*(x-25) for x in xWerte]
pyplot.plot(xWerte, yWerte, color='blue')
pyplot.show()

Siehe etwa die Erklärungen (und Quizzes) zu Listen und Strings auf https://www.w3schools.com/python/default.asp.


1)
und sogar Listen
  • lehrkraefte/snr/informatik/glf22/python/listen.txt
  • Last modified: 2023/11/21 12:37
  • by Olaf Schnürer