Grundstruktur Listenbearbeitung#
Hinweis 2023-10-13: Viele der Beispiele lassen sich mit einer List Comprehension wesentlich eleganter formulieren. Aber eine List Comprehension versteht man nur, wenn man die Beispiele verstanden hat.
Also zunächst mal “zu Fuß” mit einer expliziten for-Schleife und manuellem Konstruieren der Ergebnis-Liste.
Später dann die Aufgabe “Stellen Sie die bereits gelöste Aufgabe mit einer List-Comprehension dar!”
Anwendungsbeispiel#
Gegeben: eine Liste von Klausurnoten.
z.B.
[ 1, 2, 5, 3, 1]
Annahme: Studierende dürfen Fehlversuche streichen.
Gesucht: Eine Liste sowie der Notenschnitt von allen bestandenen Klausuren.
z.B.
[ 1, 2, 3, 1]
, Schnitt:1.75
# Eingabe
Liste_input = [ 1, 2, 5, 3, 1]
# Ausgabe
Liste_output = []
Summe = 0
# Objekt nimmt nacheinander jeden Wert aus der Eingabeliste an
for x in Liste_input:
# erfüllt das x alle gewünschten Eigenschaften?
if x < 5:
# x an die Ausgabeliste anhängen
Liste_output.append( x )
# x zur Summe hinzuaddieren
Summe += x
Schnitt = Summe / len( Liste_output )
print("übernommene Noten:", Liste_output, "Schnitt:", Schnitt )
übernommene Noten: [1, 2, 3, 1] Schnitt: 1.75
Als Vorschau dasselbe mit einer List-Comprehension:
# List Comprehension
Liste_output = [ x for x in Liste_input if x < 5 ]
Schnitt = sum( Liste_output ) / len( Liste_output )
# modernere Printsyntax mit f-String
print(f"übernommene Noten: {Liste_output} Schnitt: {Schnitt}" )
übernommene Noten: [1, 2, 3, 1] Schnitt: 1.75
Erweiterung: “gut” ist Note 2#
Die obige Grundstruktur lässt sich nun erweitern. So seien die Klausurnoten nicht nur durch Zahlen, sondern alternativ auch durch Text gegeben.
z.B.
Liste_input = [ 1, 2, 5, "krank", "befriedigend", "im Ausland", "mit Auszeichnung"]
Lösungsansatz: Bilde Text über ein dict auf eine Note ab.
z.B.
Note_aus_Text = {"sehr gut": 1, "mit Auszeichnung": 1, ...: ... }
Note_aus_Text = {"sehr gut": 1, "gut": 2,
"befriedigend": 3, "ausreichend": 4,
"mangelhaft": 5, "ungenügend": 6,
"mit Auszeichnung": 1,
"krank": None}
Liste_input = [ 1, 2, 5, "krank", "befriedigend", "im Ausland", "mit Auszeichnung"]
Liste_output = []
Summe = 0
for x in Liste_input:
# haben wir eine Zahl?
if isinstance(x, (float, int)):
Note = x
# oder haben wir einen uns bekannten Text?
elif x in Note_aus_Text:
Note = Note_aus_Text[x]
# nichts erkannt
else:
Note = None
if Note != None and Note <= 4:
Liste_output.append(Note)
Summe += Note
Schnitt = Summe / len(Liste_output)
print("übernommene Noten:", Liste_output, "Schnitt:", Schnitt )
übernommene Noten: [1, 2, 3, 1] Schnitt: 1.75
Slicing#
minimale Einführung hier, quasi Vorausschau, nur um das Sprachelement zu zeigen. Ausführlicher z.B. https://note.nkmk.me/en/python-slice-usage/
l = [ 'a', 'b', 'c', 'd', 'e', 'f']
l[0:3]
['a', 'b', 'c']
l[0] # die Zählung beginnt mit 0
'a'
l[0:2] # wählt l[0] und l[1] aus, denn l[2] ist nicht mehr 'drinn'
['a', 'b']
l[0:5:2] # l[0] bis l[4] in Zweierschritten
['a', 'c', 'e']
[ 'a', 'b', 'c', 'd', 'e', 'f'][0:5:2] # ein Slice einer direkt angegebenen Liste
['a', 'c', 'e']
Insbeondere auch Strings sind sliceables:
s = "abcdef"
s[0:5:2]
'ace'
Lernerfolskontrolle: Erkläre die Syntax
[0,1,2][0:1:2]
Was kommt ‘raus?’
Verallgemeinerung#
Verallgemeinerung der Grundstruktur “durch eine Liste durchgehen”: Durchgehen kann man auch durch ein
dict
Generator
range()
Zufallszahlen
Durchgehen durch ein dict#
z.B.
{ "Januar": 31, "Februar": 28, "März": 31 }
In einem Dict haben wir zur Verfügung die Methoden
keys()
values()
items()
Beispiele:
# Tage im Monat
TiM = { "Januar": 31, "Februar": 28, "März": 31, "April": 30, "Mai": 31 }
for x in TiM:
print(x)
Januar
Februar
März
April
Mai
for x in TiM.keys():
print(x)
Januar
Februar
März
April
Mai
for x in TiM.values():
print(x)
31
28
31
30
31
Interessant ist die Methode items()
. Sie gibt zwei Werte zurück!
# x zeigt hier auf ein Zweitupel
for x in TiM.items():
print( x[0:2] )
('Januar', 31)
('Februar', 28)
('März', 31)
('April', 30)
('Mai', 31)
# hier werden die 2 Rückgabewerte von items() direkt den zwei Variablen zugewiesen
for ( p, q ) in TiM.items():
print("p:", p, "q:", q)
p: Januar q: 31
p: Februar q: 28
p: März q: 31
p: April q: 30
p: Mai q: 31
# die Klammern kann man auch weglassen
for p, q in TiM.items():
print("p:", p, "q:", q)
p: Januar q: 31
p: Februar q: 28
p: März q: 31
p: April q: 30
p: Mai q: 31
Durchgehen durch eine automatisch generierte Liste von Zahen: range()#
Erklärung zu range()
: Googeln hilft, Erklärungen gibt es im Netz zuhauf. Hier nur ein Beispiel:
for i in range(1, 5):
print(i)
1
2
3
4
Man bemerke: Die erste Zahl ist inkludiert, die zweite excludiert.
Liste von Zufallszahlen#
siehe Doku: https://docs.python.org/3/library/random.html
import random
# erzeuge 5 Zufallszahlen zwischen 2000 und 2024
for i in range(5):
print(random.randrange(2000, 2024))
2012
2018
2000
2013
2012
Beispielaufgaben#
Beispielaufgaben unterschiedlicher Schwierigkeit, die aber alle mit dem Grundmuster plus ein paar einfache Operationen lösbar sind.
Häufigkeit von Elementen einer Liste#
Gegeben: Eine Liste z.B. von Buchstaben
Buchstabenliste = list("Hallo Welt!")
print(Buchstabenliste)
['H', 'a', 'l', 'l', 'o', ' ', 'W', 'e', 'l', 't', '!']
x = {"a": 7 }
x["a"] = 1000
x
{'a': 1000}
x["b"] = 2000
x
{'a': 1000, 'b': 2000}
# das erzeugt einen Fehler
# x["c"] += 1
# Recherche-Aufgabe: Statt den Fehler abzufangen
# kann man einen Default-Wert angeben: Wie?
gesucht: ein Dict, das für jeden Kleinbuchstaben die Häufigkeit angibt.
Haeufigkeit = {}
for b in Buchstabenliste:
if b in "abcdefghijklmnopqrstuvwxyzöäüß":
# Ist der key b neu für uns?
# key neu anlegen und Zähler mit 1 initialisieren
if b not in Haeufigkeit:
Haeufigkeit[b] = 1
# oder kennen wir den key schon?
# Zähler um 1 erhöhen!
else:
Haeufigkeit[b] += 1
print(Haeufigkeit)
{'a': 1, 'l': 3, 'o': 1, 'e': 1, 't': 1}
Set aus Liste erzeugen#
Dafür gibt es eigentlich die Funktion set()
. Aber wir kennen diese Funktion noch nicht, wir wollen sie programmieren.
Gegeben: Eine Liste L1
von Zahlen.
Gesucht: eine zweite Liste L2
, in der jede Zahl aus L1
nur einmal vorkommt. Die Reihenfolge ist egal; insbesondere muss L2
nicht sortiert sein.
Tupel in einer Liste bearbeiten: Zeitabschnitte#
Gegeben:
eine Liste des Beginns und Ende wichtiger Zeitabschnitte. Bei Zeitabschnitten, die bis heute andauern, ist als Ende
None
angegeben.z.B.
K = [ (1939, 1945), (1955, 1975), (1979, 1989), (1980, 1988), (2003, 2011), (1991, 2001), (2011, 2011), (2014, None), (2014, None), (1988, None), (2022, None), (2023, None) ]
Gesucht:
Eine Liste von Dreitupeln, bei denen zu jedem Zeitabschnitt auch die Dauer angegeben ist.
z.B.
K_Dauer = [ (1939, 1945, 7), ..., (2011, 2011, 1), (1988, None, None) ]
Eine Menge des Anfangs der Zeitabschnitte, die bis heute andauern.
z.B.
K_andauernd = { 2014, 1988, 2022 }