~~NOTOC~~ ====== 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 ... 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, strings((und sogar Listen))) 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 ''[]'' 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). ===== Schleifen über Listen ===== 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) 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. Verwende das Rechenzeichen ''%'', das den Rest einer ganzzahligen Division liefert. Du musst eine zusätzliche Variable ''index'' verwenden, die angibt, das wievielte Element der Liste gerade betrachtet wird. ---- Lösungen zu ergänzen! ===== Aufgabe: Quiz mit Fragen und Antworten in einer 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"] ===== Modifikation von Listen ===== 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() ... 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 ''.()'' aufruft: * ''append()'': Das Argument '''' 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()'': Das Element an Position '''' wird gelöscht und zurückgeliefert. * ''insert(, )'': An Position '''' wird das Element '''' eingefügt (die Elemente dahinter rücken eine Position weiter). * ''count()'': Zählt, wie oft das '''' in der Liste auftaucht. * ''index()'': Die erste Position, an der '''' in der Liste auftaucht, wird zurückgeliefert. (Fehler, falls '''' nicht in der Liste vorkommt.) * ''remove()'': Das erste in der Liste auftretende '''' 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: - Definiere eine Liste ''zahlen'' aus mindestens 10 Zahlen. - Gib das 4. Element der Liste aus. - Entferne das letzte Element aus der Liste und gib es aus. - Gib die Liste aus (dies kannst du im Folgenden immer mal wieder als Test machen). - Füge die Zahlen 17, 42, 15, 42 und 91 hinten an die Liste an. - Lösche das dritte Element aus der Liste und gib es aus. - Gib aus, wie oft die Zahl 42 in der Liste vorkommt. - Gib aus, an welcher Position die Zahl 42 (zum ersten Mal) in der Liste vorkommt. - Lösche die Zahl 42 aus der Liste. - Füge an zweiter Position die Zahl 1000 in die Liste ein. {{:lehrkraefte:snr:informatik:glf22:python:listenmodifikationen.png?400|}} ===== Aufgabe: Zahlen einlesen und in einer Liste speichern ===== 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. 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. ===== Weitere Methoden zum Erzeugen von Listen ===== ==== Listen erzeugen mit ''range'' ==== 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.) ==== Listen erzeugen mit "interner for-Schleife" ==== 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! 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: quadratzahlen = [x * x for x in range(1, 101)] 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." ==== Aufgabe zum Listen-Erzeugen mit interner for-Schleife ==== (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) (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)] ===== Extraktion von Teil-Listen ===== 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 Teste dein Verständnis mit dem folgenden Quiz meines Kollegen: https://fginfo.ksbg.ch/dokuwiki/doku.php?id=lehrkraefte:blc:informatik:glf20:programmieren:listen-quiz ====== Bonusmaterial ====== ===== Aufgabe: Sieb des Eratosthenes ===== Schreibe ein Programm, das mit Hilfe des [[https://de.wikipedia.org/wiki/Sieb_des_Eratosthenes|Siebs des Eratosthenes]] eine Liste aller Primzahlen bis zu einer gegebenen Grenze ''n'' ausgibt, etwa ''n = 1000000''. 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''. ===== Aufgabe: Snake programmieren ===== 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).) ===== Expertenwissen zur Extraktion von Teilisten ===== 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 ===== Einige Informationen zu Strings ===== 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() ===== Listen von Zahlen graphisch darstellen ===== 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() 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() ===== Weiteres Material ===== Siehe etwa die Erklärungen (und Quizzes) zu Listen und Strings auf https://www.w3schools.com/python/default.asp. ===== Verwandte Datenstrukturen: Tupel, Mengen und Wörterbücher (= tuples, sets and dictionaries) ===== Neben Listen gibt es auch Tupel, Mengen und Wörterbücher in Python, siehe etwa * https://www.w3schools.com/python/python_tuples.asp * https://www.w3schools.com/python/python_sets.asp * https://www.w3schools.com/python/python_dictionaries.asp ===== Link zur Kursseite ===== [[lehrkraefte:snr:informatik:glf22|Zur Kursseite]]