Aufwärmen · Aufgabe 1 von 7
Aufwärmen aus Modul B4: eine List Comprehension mit Bedingung. Was gibt dieser Code aus?
print([n * 2 for n in range(4) if n % 2 == 0])// I3.3 · ca. 26 Min. · Aufbau
Nach dieser Lektion geben Sie Generator-Ausdrücke direkt an sum, max, join, any und all, sagen vorher, wo any und all aufhören, und verwenden keinen verbrauchten Generator erneut.
Danach können Sie
Aufwärmen · Aufgabe 1 von 7
print([n * 2 for n in range(4) if n % 2 == 0])Vorhersagen · Aufgabe 2 von 7
squares = (n * n for n in range(4))
print(sum(squares), sum(squares))Üben · Aufgabe 3 von 7
words = ["hi", "there"]
print(sum(len(w) ____ w in words))Üben · Aufgabe 4 von 7
nums = [3, 8, 12]
print(any(n > 10 for n in nums), all(n > 2 for n in nums))Üben · Aufgabe 5 von 7
Denksport · Aufgabe 6 von 7
def check(n):
print("checking", n, end="; ")
return n > 1
print(any(check(n) for n in [0, 2, 5]))Anwenden · Aufgabe 7 von 7
Prüfen Sie Ihr Ergebnis anhand dieser Liste
Lesen Sie das ausgearbeitete Beispiel und lösen Sie dann die Übungen. Ihr Code läuft in Ihrem Browser oder auf Ihrem Computer und wird nie hochgeladen.
Ausgearbeitetes Beispiel
Jede Log-Zeile enthält eine Methode, einen Pfad, einen Statuscode und die gesendeten Bytes. Jede Kennzahl ist ein Generator-Ausdruck, der direkt an sum, any, all, max oder join geht, es entsteht also nie eine Liste von Zahlen. Das Programm summiert außerdem denselben Generator zweimal, um zu zeigen, dass der zweite Durchlauf nichts findet.
main.py
log = [
"GET /index.html 200 512",
"GET /missing 404 0",
"POST /login 200 128",
"GET /about.html 200 2048",
"GET /admin 403 0",
]
sizes = (int(line.split()[3]) for line in log)
print("bytes sent:", sum(sizes))
print("bytes again:", sum(sizes))
print("any errors:", any(int(line.split()[2]) >= 400 for line in log))
print("all GET:", all(line.startswith("GET") for line in log))
print("largest:", max(int(line.split()[3]) for line in log))
empty = ", ".join(line.split()[1] for line in log if line.endswith(" 0"))
print("empty replies:", empty)
Ausführen mit
python main.pyAusgabe
bytes sent: 2688
bytes again: 0
any errors: True
all GET: False
largest: 2048
empty replies: /missing, /adminTab rückt ein, Umschalt+Tab rückt aus. Um den Editor mit der Tastatur zu verlassen, drücken Sie Esc und dann Tab.
Beim ersten Ausführen lädt Ihr Browser Python herunter (bis zu 6.5 MB) und speichert es im Cache. Ihr Code bleibt auf Ihrem Gerät.
Übung 1 von 2
Vervollständigen Sie drei Funktionen mit je einem Generator-Ausdruck. total_length(words) liefert die Zahl der Buchstaben aller Wörter zusammen. has_long_word(words, limit) liefert True, wenn ein Wort länger als limit ist. all_lowercase(words) liefert True, wenn jedes Wort ganz kleingeschrieben ist, was str.islower() Ihnen sagt; für eine leere Liste ist es True.
Tab rückt ein, Umschalt+Tab rückt aus. Um den Editor mit der Tastatur zu verlassen, drücken Sie Esc und dann Tab.
Beim ersten Ausführen lädt Ihr Browser Python herunter (bis zu 6.5 MB) und speichert es im Cache. Ihr Code bleibt auf Ihrem Gerät.
Jeder Rumpf ist ein einziges return mit sum, any oder all um einen Generator-Ausdruck.
sum(len(w) for w in words) addiert die Längen; any(len(w) > limit for w in words) prüft auf ein langes Wort.
all(w.islower() for w in words) ist für eine leere Liste schon True, ein zusätzliches if ist also nicht nötig.
Ein möglicher Lösungsweg. Ihrer kann anders aussehen und trotzdem alle Prüfungen bestehen.
def total_length(words: list[str]) -> int:
"""Return the number of letters in all words together."""
return sum(len(w) for w in words)
def has_long_word(words: list[str], limit: int) -> bool:
"""Return True if any word is longer than limit."""
return any(len(w) > limit for w in words)
def all_lowercase(words: list[str]) -> bool:
"""Return True if every word is all lowercase."""
return all(w.islower() for w in words)
if __name__ == "__main__":
words = ["tea", "Coffee", "water"]
print(total_length(words), has_long_word(words, 5), all_lowercase(words))
Installieren Sie Python 3.14 oder neuer. Speichern Sie diese Dateien in einem Ordner, öffnen Sie dort ein Terminal und führen Sie die Befehle unten aus.
main.py
def total_length(words: list[str]) -> int:
"""Return the number of letters in all words together."""
return 0
def has_long_word(words: list[str], limit: int) -> bool:
"""Return True if any word is longer than limit."""
return False
def all_lowercase(words: list[str]) -> bool:
"""Return True if every word is all lowercase."""
return False
if __name__ == "__main__":
words = ["tea", "Coffee", "water"]
print(total_length(words), has_long_word(words, 5), all_lowercase(words))
test_main.py
from main import all_lowercase, has_long_word, total_length
def test_total_length():
"""tea, Coffee und water haben zusammen 14 Buchstaben"""
got = total_length(["tea", "Coffee", "water"])
assert got == 14, f"total_length(['tea', 'Coffee', 'water']) lieferte {got!r}, erwartet: 14"
def test_has_long_word():
"""Coffee ist länger als 5 Buchstaben, aber kein Wort ist länger als 6"""
words = ["tea", "Coffee", "water"]
got = has_long_word(words, 5), has_long_word(words, 6)
assert got == (True, False), f"has_long_word mit den Grenzen 5 und 6 lieferte {got!r}, erwartet: (True, False)"
def test_all_lowercase():
"""Coffee ist nicht kleingeschrieben, tea und water schon"""
got = all_lowercase(["tea", "Coffee"]), all_lowercase(["tea", "water"])
assert got == (False, True), f"all_lowercase lieferte {got!r}, erwartet: (False, True)"
def test_empty_list():
"""Ohne Wörter: 0 Buchstaben, kein langes Wort, alles kleingeschrieben"""
got = total_length([]), has_long_word([], 0), all_lowercase([])
assert got == (0, False, True), f"für [] lieferten die Funktionen {got!r}, erwartet: (0, False, True)"
Unter macOS und Linux tippen Sie python3, wo in diesen Befehlen python steht, wie in der ersten Lektion.
Programm ausführen:
python main.pyPrüfungen ausführen (learnrun.py muss im selben Ordner liegen):
python learnrun.py testlearnrun.py herunterladenÜbung 2 von 2
summary(numbers) liefert den kleinsten Wert, den größten Wert und den Mittelwert. Der Starter funktioniert mit einer Liste, scheitert aber, wenn numbers ein Generator ist, weil min ihn verbraucht. Sorgen Sie dafür, dass es mit jedem Iterable funktioniert, mit einem einzigen Durchlauf über numbers. Ganz ohne Zahlen löst es ValueError aus.
Tab rückt ein, Umschalt+Tab rückt aus. Um den Editor mit der Tastatur zu verlassen, drücken Sie Esc und dann Tab.
Beim ersten Ausführen lädt Ihr Browser Python herunter (bis zu 6.5 MB) und speichert es im Cache. Ihr Code bleibt auf Ihrem Gerät.
Ein Generator lässt sich nur einmal lesen, eine Liste beliebig oft.
Beginnen Sie mit values = list(numbers). Das ist der eine Durchlauf; danach verwenden Sie überall values.
if not values: raise ValueError("no numbers"). Dann return min(values), max(values), sum(values) / len(values).
Ein möglicher Lösungsweg. Ihrer kann anders aussehen und trotzdem alle Prüfungen bestehen.
from collections.abc import Iterable
def summary(numbers: Iterable[float]) -> tuple[float, float, float]:
"""Return the smallest, the largest and the mean of numbers."""
values = list(numbers)
if not values:
raise ValueError("no numbers")
return min(values), max(values), sum(values) / len(values)
if __name__ == "__main__":
print(summary(n * 1.5 for n in [2, 4, 6]))
Installieren Sie Python 3.14 oder neuer. Speichern Sie diese Dateien in einem Ordner, öffnen Sie dort ein Terminal und führen Sie die Befehle unten aus.
main.py
from collections.abc import Iterable
def summary(numbers: Iterable[float]) -> tuple[float, float, float]:
"""Return the smallest, the largest and the mean of numbers."""
smallest = min(numbers)
largest = max(numbers)
mean = sum(numbers) / sum(1 for _ in numbers)
return smallest, largest, mean
if __name__ == "__main__":
print(summary(n * 1.5 for n in [2, 4, 6]))
test_main.py
from main import summary
def test_list():
"""Eine Liste [3, 1, 2] ergibt (1, 3, 2.0)"""
got = summary([3, 1, 2])
assert got == (1, 3, 2.0), f"summary([3, 1, 2]) lieferte {got!r}, erwartet: (1, 3, 2.0)"
def test_generator():
"""Auch ein Generator-Ausdruck funktioniert"""
try:
got = summary(n * 1.5 for n in [2, 4, 6])
except ValueError as error:
raise AssertionError(f"summary(<generator>) löste ValueError aus: {error}. Ein früherer Durchlauf hat den Generator verbraucht") from None
assert got == (3.0, 9.0, 6.0), f"summary(n * 1.5 for n in [2, 4, 6]) lieferte {got!r}, erwartet: (3.0, 9.0, 6.0)"
def test_single_value():
"""Ein einzelner Wert ist Minimum, Maximum und Mittelwert"""
got = summary(iter([7]))
assert got == (7, 7, 7.0), f"summary(iter([7])) lieferte {got!r}, erwartet: (7, 7, 7.0)"
def test_empty():
"""Ohne Zahlen kommt ValueError"""
try:
got = summary([])
except ValueError:
return
raise AssertionError(f"summary([]) lieferte {got!r}, statt ValueError auszulösen")
Unter macOS und Linux tippen Sie python3, wo in diesen Befehlen python steht, wie in der ersten Lektion.
Programm ausführen:
python main.pyPrüfungen ausführen (learnrun.py muss im selben Ordner liegen):
python learnrun.py testlearnrun.py herunterladenprices = [4.5, 12.0, 3.25]
doubled = (p * 2 for p in prices)
total = sum(doubled)
biggest = max(doubled)
print(total, biggest)
Was Python ausgibt
ValueError: max() iterable argument is emptyWarum, und die Lösung
sum hat den Generator verbraucht, also bekam max einen leeren Iterator. Brauchen Sie die Werte mehr als einmal, bauen Sie mit eckigen Klammern eine Liste: doubled = [p * 2 for p in prices]. Oder schreiben Sie für jede Verwendung einen neuen Generator-Ausdruck.
nums = [1, 2, 3]
print(sum(n * n for n in nums, 10))
Was Python ausgibt
SyntaxError: Generator expression must be parenthesizedWarum, und die Lösung
Die Klammern eines Generator-Ausdrucks dürfen nur fehlen, wenn er das einzige Argument des Aufrufs ist. Mit einem zweiten Argument braucht er eigene: sum((n * n for n in nums), 10). Hier beginnt sum bei 10 zu zählen und liefert 24.
ids = [7, 12, 30]
print(", ".join(n for n in ids))
Was Python ausgibt
TypeError: sequence item 0: expected str instance, int foundWarum, und die Lösung
join verbindet nur Strings, und der Generator liefert ihm ints. Wandeln Sie im Ausdruck um: ", ".join(str(n) for n in ids) gibt 7, 12, 30 aus.
Python im Browser: Pyodide 314.0.7, MPL-2.0. Lizenz und Quellcode
5 Fragen, ohne Hinweise. Ab 80 % ist die Lektion abgeschlossen.
Erledigen Sie zuerst alle Aufgaben oben, um das Abschlussquiz freizuschalten.