Python Lernhandbuch

Kapitel 6: Funktionen

Musterlösung mit Erklärung

Deine Lösung hat die Prüfung noch nicht bestanden. Lies die Erklärung, dann versuche es erneut – möglichst ohne abzuschreiben.
Aufgabe noch einmal lesen

Schreibe die folgenden Funktionen und teste sie:

  1. ist_primzahl(n) liefert True, wenn n eine Primzahl ist, sonst False.
  2. statistik(zahlen, *, runden=2) liefert ein Dictionary mit den Schlüsseln 'min', 'max', 'mittel'. Der Mittelwert wird auf runden Stellen gerundet. Bei einer leeren Liste soll None zurückkommen.
  3. filtere(kunden, **bedingungen) bekommt eine Liste von Dictionaries und beliebig viele Schlüsselwort-Bedingungen und liefert alle Einträge, die zu allen Bedingungen passen. Beispiel: filtere(kunden, stadt='Wien', aktiv=True).
python
def ist_primzahl(n):
    if n < 2:
        return False
    for teiler in range(2, int(n ** 0.5) + 1):
        if n % teiler == 0:
            return False
    return True


def statistik(zahlen, *, runden=2):
    if not zahlen:
        return None
    return {
        'min': min(zahlen),
        'max': max(zahlen),
        'mittel': round(sum(zahlen) / len(zahlen), runden),
    }


def filtere(kunden, **bedingungen):
    ergebnis = []
    for kunde in kunden:
        passt = all(kunde.get(feld) == wert for feld, wert in bedingungen.items())
        if passt:
            ergebnis.append(kunde)
    return ergebnis


kunden = [
    {'name': 'Anna', 'stadt': 'Wien', 'aktiv': True},
    {'name': 'Ben', 'stadt': 'Graz', 'aktiv': True},
    {'name': 'Cem', 'stadt': 'Wien', 'aktiv': False},
]
print([k for k in range(20) if ist_primzahl(k)])   # [2, 3, 5, 7, 11, 13, 17, 19]
print(statistik([4, 9, 2]))                         # {'min': 2, 'max': 9, 'mittel': 5.0}
print(filtere(kunden, stadt='Wien', aktiv=True))    # nur Anna

Was passiert:

  • ist_primzahl: Es genügt, Teiler bis zur Wurzel von n zu prüfen. n ** 0.5 ist die Wurzel, int(...) + 1 macht daraus die Obergrenze für range. Das frühe return False beendet die Funktion sofort, sobald ein Teiler gefunden ist.
  • statistik: if not zahlen ist wahr bei einer leeren Liste (Kapitel 2, Wahrheitswerte). Das * vor runden erzwingt, dass man runden=3 mit Namen schreibt. Das macht Aufrufe lesbarer.
  • filtere: **bedingungen sammelt stadt='Wien', aktiv=True zu einem Dictionary. all(...) prüft, ob jede Bedingung erfüllt ist. kunde.get(feld) liefert None statt eines Fehlers, wenn das Feld fehlt.

Warum so: Kleine Funktionen mit einer klaren Aufgabe sind leicht zu testen und wiederzuverwenden. Die Funktion filtere zeigt, wie **kwargs flexible Schnittstellen ermöglichen, genau wie du sie später bei Datenbank- und API-Bibliotheken siehst.