lehrkraefte:snr:informatik:fachdidaktik:list-comprehension

Fortgeschrittene Techniken für Listen samt Aufgaben zu Goethes Faust

Bitte anschauen: Begrüßungsvideo

In vorigen Lektionen hast du bereits Listen kennengelernt. Heute wirst du neben einigen Funktionen für Listen insbesondere list comprehension kennenlernen, eine elegante Methode zur Definition von Listen. Die Vermittlung dieser Inhalte wird vor allem durch Lern-Videos (inklusive kleiner Aufgaben) geschehen.

Danach gibt es als Lernkontrolle einige Aufgaben zum Text von Goethes Faust - dieser Text wird dir als Liste zur Verfügung gestellt. Beispielsweise wirst du herausfinden, wie viele Wörter welcher Länge in Goethes Faust vorkommen und wie man dieses Ergebnis in einem Säulendiagramm graphisch darstellen kann.

Außerdem wirst du herausfinden, dass es im gesamten Faust nur 23 Palindrome (= Wörter, die von vorne wie von hinten gelesen vorkommen) gibt.

  • Checke, ob du die im nächsten Abschnitt beschriebenen Vorkenntnisse hast.
  • Wenn dies der Fall ist, sollten Aufgabe 0 und Aufgabe 1 schnell gelöst sein.
  • Schau dir das Erklärvideo zu Listenfunktionen an und löse die darin gestellten Aufgaben.
  • Schau dir das Erklärvideo zu list comprehension an und löse die darin gestellten Aufgaben.
  • Bearbeite die Aufgaben 2, 3 und 4 zur Erprobung des Gelernten.

Wir nehmen an, dass du

  • mindestens die im folgenden Link erklärten Sachverhalte über Listen und Strings kennst: Vorkenntnisse

Nützlich, aber nicht zwingend erforderlich ist es, wenn du mit Visual Studio Code (= VS Code) vertraut bist:

  • Du weißt, wie man dort Python-Programme schreibt und ausführt (Ctrl+F5).
  • Du weißt, wie man im Terminal von VS Code eine interaktive Python-Session öffnet und benutzt.
  • Die Vorbereitungen in Aufgabe 0 im nächsten Abschnitt stellen dich vor keinerlei Probleme.

Erstelle ein neues Verzeichnis namens list-comprehension für deine heutigen Python-Programme.

Öffne dieses Verzeichnis mit VS Code und öffne darin eine neue, leere Datei mit dem Namen faust-analyse.py. Kopiere den folgenden Python-Code in diese Datei und speichere sie ab. Hinweis: Durch Anklicken des “Clipboard-Symbols” rechts oben im Fenster um den Code kannst du den Python-Code direkt in die Zwischenablage kopieren.

eingabeDatei = open("faust-1-und-2.txt", encoding='utf-8')    # Die Angabe des Encodings ist unter Windows nötig.
wortliste = eingabeDatei.read().splitlines()
eingabeDatei.close()
print("Berühmte Passage:")
print(wortliste[2454:2470])

Die folgende Datei enthält alle Wörter aus Goethes Faust (Teil I und Teil II) in der richtigen Reihenfolge. Speichere sie in deinem neu erstellten Verzeichnis ab, indem du sie mit der rechten Maustaste anklickst und “Speichern unter”/“Save as” auswählst.

faust-1-und-2.txt

Führe das Python-Programm aus (per Ctrl-F5 in VS Code) - wenn du alles richtig gemacht hast, wird eine berühmte Passage aus Faust (als Liste von Strings) ausgegeben.

Erwartete Ausgabe

Erwartete Ausgabe

Berühmte Passage:
['Habe', 'nun', 'ach', 'Philosophie', 'Juristerei', 'und', 'Medizin', 'Und', 'leider', 'auch', 'Theologie', 'Durchaus', 'studiert', 'mit', 'heißem', 'Bemühn']

Falls es wider Erwarten nicht mit dem Einlesen der Wörter aus der Datei klappt:

Im folgenden Python-Programm ist die faustsche Wörterliste explizit in der ersten (sehr langen) Zeile angegeben: faust-analyse-wortliste-explizit.py

Speichere diese Datei (per Anklicken mit der rechten Maustaste) ab und führe sie aus. Arbeite im Folgenden mit dem Python-Programm faust-analyse-wortliste-explizit.py statt mit faust-analyse.py.

Alle folgenden Aufgaben zur Analyse des Faust-Textes starten mit dem Programm faust-analyse.py als Grundgerüst.

Ergänze das Programm faust-analyse.py so (bei den ersten drei Teilaufgaben genügt jeweils eine neue Zeile am Ende des Python-Programms), dass

  • (1a) die Anzahl der Wörter in Goethes Faust ausgegeben wird;
  • (1b) die ersten 10 Wörter als Liste ausgegeben werden (es handelt sich um Wörter aus dem Inhaltsverzeichnis);
  • (1c) die letzten 10 Wörter als Liste ausgegeben werden;
  • (1d) die berühmte Passage (= der Anfang von Fausts Monolog) rückwärts ausgegeben wird (als Liste).

Wenn du willst, kannst du das Programm unter einem beliebigen Namen deiner Wahl (etwa aufgabe-1.py) abspeichern.

Hinweise für 1a-1c

Hinweise für 1a-1c

Hinweis zu 1d

Hinweis zu 1d

Verwende eine Zusatzvariable faustMonolog, die die Passage als Liste enthält.

Weiterer Hinweis zu 1d

Weiterer Hinweis zu 1d

Gib die Liste faustMonolog = wortliste[2454:2470] rückwärts aus.


Antwort zu 1a

Antwort zu 1a

76101 Wörter

Antwort zu 1b

Antwort zu 1b

['Zueignung', 'Vorspiel', 'auf', 'dem', 'Theater', 'Prolog', 'im', 'Himmel', 'Nacht', 'Vor']

Antwort zu 1c

Antwort zu 1c

['Unbeschreibliche', 'Hier', 'ists', 'getan', 'Das', 'Ewig', 'Weibliche', 'Zieht', 'uns', 'hinan']

Antwort zu 1d

Antwort zu 1d

['Bemühn', 'heißem', 'mit', 'studiert', 'Durchaus', 'Theologie', 'auch', 'leider', 'Und', 'Medizin', 'und', 'Juristerei', 'Philosophie', 'ach', 'nun', 'Habe']

Lösungsvorschlag

Lösungsvorschlag

eingabeDatei = open("faust-1-und-2.txt", encoding='utf-8')
wortliste = eingabeDatei.read().splitlines()
eingabeDatei.close()
print("Berühmte Passage:")
print(wortliste[2454:2470])
# Teilaufgabe 1a
print("Anzahl Wörter:")                 # Diese Zeile war nicht verlangt - es ist aber natürlich sinnvoll, jede Ausgabe zu erklären.
print(len(wortliste))
# Teilaufgabe 1b
print("Erste 10 Wörter:")
print(wortliste[:10])
# Teilaufgabe 1c
print("Letzte 10 Wörter:")
print(wortliste[-10:])
# Teilaufgabe 1d
print("Fausts Monolog rückwärts:")
faustMonolog = wortliste[2454:2470]
print(faustMonolog[::-1])
# Alternative 1 zu 1d:
# print(wortliste[2469:2453:-1])       # und NICHT: print(wortliste[2470:2454:-1])
# Alternative 2 zu 1d:
# print(wortliste[2454:2470][::-1])

Schau nun das hier verlinkte Erklärvideo an.

Darin werden die fünf Listen-Funktionen1) len, max, min, sorted, reversed und die drei Listen-Methoden append, count, index erklärt; das Video endet mit einer Übungsaufgabe dazu.

Die Bezeichnung “list comprehension” ist historisch bedingt und nicht besonders glücklich gewählt. Es geht darum, neue Listen mit möglichst leicht verständlicher Syntax zu definieren.

List comprehension wird in dem hier verlinkten Video erklärt.2)

Erklärt werden “list comprehension-Ausdrücke” wie etwa [i**2 for i in range(1, 101)] oder [i**2 for i in range(1, 101) if i**2 <= 1000] als Vereinfachungen des sukzessiven Listenaufbaus mit for-Schleifen (mit Bedingung). Diese Notation ähnelt der mathematischen “Set-builder notation” $\{x^2 \mid x \in \{1, 2, 3, \dots, 100\} \text{ mit } x^2 \leq 100\}$.

Ergänze das Programm faust-analyse.py (aus Aufgabe 0: Vorbereitung) so, dass

  • (2a) ausgegeben wird, wie oft das Wort Hexe in Goethes Faust vorkommt;

Hinweis

Hinweis

  1. Möglichkeit: Die Methode <Name der Liste>.count(…) zählt, wie oft ein Element in einer Liste auftaucht.
  2. Möglichkeit: Verwende die Längenfunktion len(…) und list comprehension.

Antwort

Antwort

8 Mal


  • (2b) ausgegeben wird, an welcher Position das Wort Hexe zum ersten Mal auftaucht;

Hinweis

Hinweis

Die Methode <Name der Liste>.index(…) liefert den Index des ersten Auftretens eines Elements einer Liste.

Antwort

Antwort

An Position 15247 (in Informatik-Zählweise).


  • (2c) der “Kontext” des ersten Auftretens des Wortes Hexe ausgegeben wird; dieser “Kontext” soll als Liste von 21 Wörtern um dieses Wort herum mit dem Wort Hexe in der Mitte ausgegeben werden.

Hinweis

Hinweis

Gib eine geeignete Teilliste der Liste wortliste aus. Berechne Start- und Endindex aus der Zahl in der vorigen Teilaufgabe.

Weiterer Hinweis

Weiterer Hinweis

Verwende die Syntaxwortliste[<Startindex>:<Endindex>].

Antwort

Antwort

['mir', 'gar', 'nicht', 'an', 'MEPHISTOPHELES', 'So', 'muß', 'denn', 'doch', 'die', 'Hexe', 'dran', 'FAUST', 'Warum', 'denn', 'just', 'das', 'alte', 'Weib', 'Kannst', 'du']

  • (2d) eine Liste aller Positionen (in informatischer Zählweise) ausgegeben wird, an denen das Wort Hexe erscheint.

Hinweis

Hinweis

Die gesuchte Liste ist eine Teilliste der Liste aller Zahlen von 0 bis zur Länge unserer Wortliste (minus Eins). Beschreibe diese Teilliste durch eine geeignete list comprehension.

Weiterer Hinweis

Weiterer Hinweis

Der list comprehension-Ausdruck [i for i in range(len(wortliste)) if …] beschreibt diese Teilliste, wenn die drei Punkte geeignet ersetzt werden.

Antwort

Antwort

[15247, 15980, 16094, 16483, 16855, 16903, 16927, 25973]

Lösungsvorschlag

Lösungsvorschlag

eingabeDatei = open("faust-1-und-2.txt", encoding='utf-8')
wortliste = eingabeDatei.read().splitlines()
eingabeDatei.close()
print("Berühmte Passage:")
print(wortliste[2454:2470])
# Teilaufgabe 2a
print("Anzahl des Wortes 'Hexe':")
print(wortliste.count("Hexe"))
# Alternative:
# print(len([x for x in wortliste if x == "Hexe"]))
# Teilaufgabe 2b
print("Position des ersten Auftretens des Wortes 'Hexe':")
print(wortliste.index("Hexe"))
# Teilaufgabe 2c
print("Kontext des ersten Auftretens von 'Hexe':")
erstePositionHexe= wortliste.index("Hexe")
print(wortliste[erstePositionHexe-10:erstePositionHexe+11])
# Teilaufgabe 2d
print("Liste der Positionen, an denen das Wort 'Hexe' auftritt:")
print([i for i in range(len(wortliste)) if wortliste[i] == "Hexe"])

Starte wieder mit dem Programm faust-analyse.py (aus Aufgabe 0: Vorbereitung).

  • (3a) Definiere eine Liste namens wortlaengen, deren Einträge die Längen der Wörter aus Goethes Faust sind: Der nullte Eintrag ist die Länge des nullten Worts, der erste Eintrag die Länge des zweiten Worts usw.

Hinweis

Hinweis

Diese List kann mit einer list comprehension definiert werden: wortlaengen = [… for w in wortliste].


  • (3b) Speichere die Länge des längsten Wortes (oder der längsten Wörter) in Goethes Faust in der Variable maxLaenge und gib diese Variable aus.

Hinweis

Hinweis

Verwende die Funktion max(…).

Antwort

Antwort

Die maximale Wortlänge ist 32.


  • (3c) Definiere eine Liste anzahlBeiLaenge, deren Einträge angeben, wie viele Wörter einer gegebenen Länge vorkommen: Der nullte Eintrag ist Null (= die Anzahl aller Wörter der Länge Null), der erste Eintrag ist die Anzahl aller Wörter der Länge eins, der zweite Eintrag die Anzahl aller Wörter der Länge zwei usw.

    Gib diese Liste aus.

Hinweis

Hinweis

Die Methode .count() zählt, wie oft ein Eintrag in einer Liste vorkommt.

Weiterer Hinweis

Weiterer Hinweis

Die gesuchte Liste kann mit einer list comprehension definiert werden: anzahlBeiLaenge = [… for i in range(…)].

Weiterer Hinweis

Weiterer Hinweis

anzahlBeiLaenge = [wortlaengen.count(…) for i in range(maxLaenge + 1)].


Lösungsvorschlag

Lösungsvorschlag

eingabeDatei = open("faust-1-und-2.txt", encoding='utf-8')
wortliste = eingabeDatei.read().splitlines()
eingabeDatei.close()
print("Berühmte Passage:")
print(wortliste[2454:2470])
# Teilaufgabe 3a
wortlaengen = [len(w) for w in wortliste]
# Teilaufgabe 3b
maxLaenge = max(wortlaengen)
print("Maximale Wortlänge:")
print(maxLaenge)
# Teilaufgabe 3c
anzahlBeiLaenge = [wortlaengen.count(i) for i in range(maxLaenge + 1)]
print("Liste der Wörter bei gegebener Wortlänge (Lesehilfe: der n-te Eintrag gibt an, wie viele Wörter n Buchstaben haben):")
print(anzahlBeiLaenge)

Darstellung als Säulendiagramm

Mit der Python-Bibliotheken matplotlib (für “Library for mathematical plots) ist es einfach, das Ergebnis der Text-Analyse in Aufgabe 3 graphisch als Säulendiagramm darzustellen: Kopiere den folgenden Code-Block ans Ende deines Programms und führe das Programm aus (falls dies nicht funktioniert, musst du vermutlich die Bibliothek matplotlib installieren, siehe die “gelbe” Glühbirnen-Box unter der folgenden Code-Box).

from matplotlib import pyplot as plt
 
def zeichneSaeulendiagramm(xWerte, yWerte, titel, xBeschriftung, yBeschriftung):
    # xWerte: Liste der Werte auf der horizontalen Achse
    # yWerte: Liste der zugehörigen Funktionswerte
    # titel: Titel der Graphik
    # xBeschriftung: Text unter der horizontalen Achse
    # yBeschriftung: Text links der vertikalen Achse
    plt.figure("Säulendiagramm-Fenster")
    plt.title(titel)
    plt.xlabel(xBeschriftung)
    plt.ylabel(yBeschriftung)
    plt.bar(xWerte, yWerte, color='blue')
    plt.xticks(xWerte, xWerte, rotation='horizontal')
    plt.tight_layout()
    plt.show()
 
zeichneSaeulendiagramm(range(maxLaenge + 1), anzahlBeiLaenge, 'Anzahl der Wörter gegebener Länge', 'Wortlänge', 'Anzahl der Wörter')

Eventuell musst du die Bibliothek matplotlib installieren. Dies geht (unter Windows) mit dem Programm “Befehlszeile”/“Command prompt” wie folgt: Gib die beiden folgenden Zeilen dort ein, jeweils gefolgt von Return.

python -m pip install -U pip
python -m pip install -U matplotlib

Der erste Befehl installiert pip bzw. führt ein Upgrade davon durch. Die eigentliche Installation der Bibliothek ist dann der zweite Befehl.

Hier stellt sich etwa die “Forschungsfrage”: Kann man einen Autor (bzw. eine Sprache) anhand der Buchstabenhäufigkeiten erkennen?

Palindrome sind Wörter (und manchmal auch Sätze), die von vorne wie von hinten gelesen dasselbe Wort liefern, vgl. https://de.wikipedia.org/wiki/Palindrom.

Starte wieder mit dem Programm faust-analyse.py.

Die Liste wortliste enthält viele Wörter mehrfach; beispielsweise taucht das Wort “aber” mehrfach auf - überdies taucht es großgeschrieben als “Aber” auf.

Ergänze das Programm am Ende um die Code-Zeile

wortlisteOhneWiederholungen = list({x.lower() for x in wortliste})

Die Liste wortlisteOhneWiederholungen enthält dann alle Wörter aus Goethes Faust in Kleinschreibung ohne Wiederholungen.3)

Ergänze das Programm so, dass

  • (4a) eine alphabetisch sortierte Liste aller Wörter der Länge 19 ausgegeben wird.

Hinweis

Hinweis

Die Funktion sorted(…) sortiert eine Liste (genauer nimmt sie eine Liste entgegen und liefert deren Sortierung zurück).

Weiterer Hinweis

Weiterer Hinweis

Erstelle mit einer geeigneten list comprehension eine Liste aller Wörter der Länge 19.

Antwort

Antwort

List der Wörter der Länge 19, alphabetisch sortiert:
['fratzengeisterspiel', 'menschenfresserisch', 'rechtsgelehrsamkeit', 'scharfangeschloßnem', 'sonnedurchstrahlten', 'unwiederbringlichen', 'zweigleinbeflügelte']

  • (4b) Eine alphabetisch sortierte Liste aller Wörter, die mit dem Buchstaben 'q' beginnen, ausgegeben wird.

Hinweis

Hinweis

Gehe ähnlich vor wie bei der vorigen Aufgabe. Den ersten Buchstaben eines Strings s bekommt man per s[0].

Antwort

Antwort

Liste der mit 'q' beginnenden Wörter, alphabetisch sortiert:
['quadrat', 'qual', 'qualen', 'qualität', 'qualitäten', 'qualm', 'qualmend', 'quammig', 'quappig', 'quark', 'quasten', 'quecksilber', 'quell', 'quelle', 'quellen', 'quellt', 'quem', 'quentchen', 'quer', 'quetschend', 'quetschender', 'quid', 'quidquid', 'quillen', 'quillend', 'quillt', 'quintessenz', 'quirlt', 'quäle', 'quälen', 'quälte']

  • (4c) Eine Liste aller Palindromwörter in Goethes Faust ausgegeben wird; außerdem soll die Anzahl aller Palindromwörter ausgegeben werden. (Genauer sind damit diejenigen Wörter im Faust gemeint, die auch von hinten gelesen im Faust auftauchen.)

Hinweis

Hinweis

Wie kann man feststellen, ob ein String s ein Palindromwort ist?

Weiterer Hinweis

Weiterer Hinweis

Der String s[::-1] ist s rückwärts gelesen.

Weiterer Hinweis

Weiterer Hinweis

Genau dann ist s ein Palindromwort, wenn s == s[::-1] wahr ist.

Weiterer Hinweis

Weiterer Hinweis

Verwende list comprehension, um die gesuchte Liste zu definieren.

Weiterer Hinweis

Weiterer Hinweis

[… for s in wortlisteOhneWiederholungen if …]

Antwort

Antwort

Liste der Palindrome, alphabetisch sortiert:
['a', 'aha', 'beleb', 'bub', 'e', 'ehe', 'höh', 'i', 'ii', 'madam', 'neben', 'nennen', 'neuen', 'nun', 'o', 'retter', 's', 'stets', 'tat', 'tot', 'tut', 'tät', 'uhu']
Anzahl der Palindrome:
23

Lösungsvorschlag

Lösungsvorschlag

eingabeDatei = open("faust-1-und-2.txt", encoding='utf-8')
wortliste = eingabeDatei.read().splitlines()
eingabeDatei.close()
print("Berühmte Passage:")
print(wortliste[2454:2470])
wortlisteOhneWiederholungen = list({x.lower() for x in wortliste})
# Teilaufgabe 4a
wortliste19 = [s for s in wortlisteOhneWiederholungen if len(s) == 19]
print("List der Wörter der Länge 19, alphabetisch sortiert:")
print(sorted(wortliste19))
# Teilaufgabe 4b
wortlisteQ = [s for s in wortlisteOhneWiederholungen if s[0] == "q"]
print("Liste der mit 'q' beginnenden Wörter, alphabetisch sortiert:")
print(sorted(wortlisteQ))
# Teilaufgabe 4c
palindromliste = [s for s in wortlisteOhneWiederholungen if s == s[::-1]]
print("Liste der Palindrome, alphabetisch sortiert:")
print(sorted(palindromliste))
print("Anzahl der Palindrome:")
print(len(palindromliste))

Siehe Bonusmaterial.

  • Verschachtelte Listen
  • Kopieren von Listen (shallow copy, deep copy) und dadurch motiviert:
  • mutable and immutable data types (deutsch etwa: veränderliche und unveränderliche Datentypen); vlg. meine bisherigen Versuche dazu: listen_sind_mutabel_veraenderlich_englisch_mutable oder noch genauer variablen-in-python.
  • Wie bekomme ich einen beliebigen Text aus dem Internet in Listenform?

1)
Es handelt sich dabei um sogenannte built-in functions, vgl. https://docs.python.org/3/library/functions.html. Eine weitere solche Funktion, die man auf Listen anwenden kann, ist sum.
2)
Bisher habe ich die folgenden Versprecher bemerkt: 4:03 gemeint sind eckige Klammern; 10:03 ignoriere Kommentar mit 10 Minuten; 12:04 es sollte heißen: “Nur die hat am ANFANG ein e”
3)
Wer es genau wissen will: {x.lower() for x in wortliste} liefert die Menge aller Wörter (wobei Großbuchstaben durch Kleinbuchstaben ersetzt wurden). Diese Menge wird mit dem Befehl list(…) in eine Liste verwandelt.
  • lehrkraefte/snr/informatik/fachdidaktik/list-comprehension.txt
  • Last modified: 2022/09/14 20:28
  • by Olaf Schnürer