Verschachtelte Datenstrukturen in Python
Lerne den Umgang mit verschachtelten Listen, Dictionaries und JSON-Daten in Python. Mit praxisnahen Beispielen wie Schüler-Noten-System und Kontaktliste.
Verschachtelte Datenstrukturen in Python
In der Praxis bestehen Daten selten aus einfachen Listen oder einzelnen Dictionaries. Meistens arbeiten wir mit verschachtelten Strukturen: Listen in Listen, Dictionaries in Listen, Listen in Dictionaries und viele Kombinationen mehr. In diesem Tutorial lernst du, wie du solche Strukturen erstellst, darauf zugreifst und sie effektiv verarbeitest.
Listen von Listen (2D-Listen / Matrizen)
Eine 2D-Liste ist eine Liste, die andere Listen als Elemente enthält. Damit lassen sich tabellarische Daten oder Matrizen darstellen.
# Eine 3x3 Matrix
matrix = [
[1, 2, 3],
[4, 5, 6],
[7, 8, 9]
]
# Zugriff: matrix[zeile][spalte]
print(matrix[0]) # [1, 2, 3] -- erste Zeile
print(matrix[0][0]) # 1 -- erstes Element der ersten Zeile
print(matrix[1][2]) # 6 -- dritte Spalte der zweiten Zeile
print(matrix[2][1]) # 8 -- zweite Spalte der dritten Zeile
# Über alle Elemente iterieren
for zeile in matrix:
for element in zeile:
print(element, end=" ")
print()
# Ausgabe:
# 1 2 3
# 4 5 6
# 7 8 9
# Mit Index iterieren
for i in range(len(matrix)):
for j in range(len(matrix[i])):
print(f"matrix[{i}][{j}] = {matrix[i][j]}")
Matrizen erstellen und bearbeiten
# Matrix mit Nullen erstellen (RICHTIG)
zeilen = 3
spalten = 4
matrix = [[0 for _ in range(spalten)] for _ in range(zeilen)]
print(matrix)
# [[0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]]
# ACHTUNG: Diese Methode ist FALSCH!
falsch = [[0] * spalten] * zeilen # Alle Zeilen sind das GLEICHE Objekt!
falsch[0][0] = 99
print(falsch) # [[99, 0, 0, 0], [99, 0, 0, 0], [99, 0, 0, 0]] -- ALLE geändert!
# Diagonale setzen
for i in range(min(zeilen, spalten)):
matrix[i][i] = 1
print(matrix)
# [[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 0]]
# Spalte extrahieren
def spalte_holen(matrix, spalten_index):
return [zeile[spalten_index] for zeile in matrix]
m = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
print(spalte_holen(m, 1)) # [2, 5, 8]
# Matrix transponieren (Zeilen und Spalten tauschen)
def transponieren(matrix):
return [[zeile[i] for zeile in matrix] for i in range(len(matrix[0]))]
original = [[1, 2, 3], [4, 5, 6]]
transponiert = transponieren(original)
print(transponiert) # [[1, 4], [2, 5], [3, 6]]
Stundenplan als 2D-Liste
# Stundenplan (Zeilen = Stunden, Spalten = Tage)
tage = ["Mo", "Di", "Mi", "Do", "Fr"]
stundenplan = [
["Mathe", "Deutsch", "Englisch", "Physik", "Sport"],
["Deutsch", "Mathe", "Kunst", "Englisch","Musik"],
["Bio", "Englisch", "Mathe", "Chemie", "Mathe"],
["Sport", "Physik", "Deutsch", "Mathe", "Bio"],
]
# Schöne Ausgabe
print(f"{'Std':<6}", end="")
for tag in tage:
print(f"{tag:<12}", end="")
print()
print("-" * 66)
for stunde, faecher in enumerate(stundenplan, 1):
print(f"{stunde}. Std ", end="")
for fach in faecher:
print(f"{fach:<12}", end="")
print()
# Alle Stunden eines bestimmten Tages
mittwoch_index = tage.index("Mi")
print(f"\nMittwoch:")
for stunde, faecher in enumerate(stundenplan, 1):
print(f" {stunde}. Stunde: {faecher[mittwoch_index]}")
Listen von Dictionaries
Diese Struktur ist besonders häufig und entspricht dem Format, das du von JSON-APIs und Datenbanken kennst.
# Liste von Schülern
schueler = [
{"name": "Anna", "alter": 16, "klasse": "10a", "note": 1.3},
{"name": "Ben", "alter": 17, "klasse": "10b", "note": 2.7},
{"name": "Clara", "alter": 16, "klasse": "10a", "note": 1.0},
{"name": "David", "alter": 17, "klasse": "10b", "note": 2.3},
{"name": "Eva", "alter": 16, "klasse": "10a", "note": 1.7},
]
# Auf einzelne Datensätze zugreifen
print(schueler[0]["name"]) # Anna
print(schueler[2]["note"]) # 1.0
# Alle Namen ausgeben
for s in schueler:
print(f"{s['name']} (Klasse {s['klasse']}): Note {s['note']}")
# Filtern: Alle Schüler mit Note besser als 2.0
gute_schueler = [s for s in schueler if s["note"] < 2.0]
print(f"\nGute Schüler ({len(gute_schueler)}):")
for s in gute_schueler:
print(f" {s['name']}: {s['note']}")
# Sortieren nach Note
nach_note = sorted(schueler, key=lambda s: s["note"])
print("\nRangliste:")
for platz, s in enumerate(nach_note, 1):
print(f" {platz}. {s['name']}: {s['note']}")
# Durchschnittsnote berechnen
durchschnitt = sum(s["note"] for s in schueler) / len(schueler)
print(f"\nDurchschnittsnote: {durchschnitt:.2f}")
# Schüler nach Klasse gruppieren
from collections import defaultdict
klassen = defaultdict(list)
for s in schueler:
klassen[s["klasse"]].append(s["name"])
print("\nKlassen:")
for klasse, namen in sorted(klassen.items()):
print(f" {klasse}: {', '.join(namen)}")
Dictionaries mit Listen als Werte
# Kurse und ihre Teilnehmer
kurse = {
"Python": ["Anna", "Ben", "Clara"],
"JavaScript": ["David", "Eva", "Anna"],
"Datenbanken": ["Ben", "Clara", "David", "Eva"]
}
# Zugriff
print(kurse["Python"]) # ['Anna', 'Ben', 'Clara']
print(kurse["Python"][0]) # Anna
print(len(kurse["JavaScript"])) # 3
# Teilnehmer hinzufügen
kurse["Python"].append("Frank")
print(kurse["Python"]) # ['Anna', 'Ben', 'Clara', 'Frank']
# Neuen Kurs erstellen
kurse["HTML/CSS"] = ["Gina", "Hannah"]
# Über alle Kurse iterieren
print("\nKursübersicht:")
for kurs, teilnehmer in kurse.items():
print(f"\n {kurs} ({len(teilnehmer)} Teilnehmer):")
for t in teilnehmer:
print(f" - {t}")
# Wer besucht die meisten Kurse?
from collections import Counter
alle_teilnehmer = []
for teilnehmer in kurse.values():
alle_teilnehmer.extend(teilnehmer)
zaehler = Counter(alle_teilnehmer)
print("\nAnzahl Kurse pro Person:")
for person, anzahl in zaehler.most_common():
print(f" {person}: {anzahl} Kurs(e)")
# Notenübersicht
noten = {
"Anna": [1.3, 2.0, 1.7, 1.0],
"Ben": [2.7, 3.0, 2.3, 2.0],
"Clara": [1.0, 1.3, 1.0, 1.7]
}
print("\nNotendurchschnitte:")
for name, noten_liste in noten.items():
schnitt = sum(noten_liste) / len(noten_liste)
print(f" {name}: {schnitt:.2f} (aus {len(noten_liste)} Noten)")
Verschachtelte Dictionaries
# Schulverwaltung
schule = {
"name": "Python-Gymnasium",
"adresse": {
"strasse": "Codestraße 42",
"plz": "10115",
"stadt": "Berlin"
},
"klassen": {
"10a": {
"klassenlehrer": "Herr Müller",
"schueler_anzahl": 28,
"faecher": ["Mathe", "Deutsch", "Englisch", "Physik"]
},
"10b": {
"klassenlehrer": "Frau Schmidt",
"schueler_anzahl": 26,
"faecher": ["Mathe", "Deutsch", "Englisch", "Chemie"]
}
},
"kontakt": {
"telefon": "030-123456",
"email": "info@python-gymnasium.de",
"website": "www.python-gymnasium.de"
}
}
# Zugriff auf verschachtelte Werte
print(schule["name"])
print(schule["adresse"]["stadt"])
print(schule["klassen"]["10a"]["klassenlehrer"])
print(schule["klassen"]["10b"]["faecher"][2])
# Sicherer Zugriff mit get()
raum = schule.get("klassen", {}).get("10c", {}).get("raum", "Nicht vorhanden")
print(raum) # Nicht vorhanden
# Verschachtelte Daten ändern
schule["klassen"]["10a"]["schueler_anzahl"] = 29
schule["kontakt"]["telefon"] = "030-654321"
Zugriff auf verschachtelte Daten
Hilfsfunktion fuer sicheren Zugriff
def sicherer_zugriff(daten, *schluessel, standard=None):
"""Greift sicher auf verschachtelte Dictionary-Werte zu."""
aktuell = daten
for s in schluessel:
if isinstance(aktuell, dict):
aktuell = aktuell.get(s, standard)
if aktuell is standard:
return standard
elif isinstance(aktuell, (list, tuple)) and isinstance(s, int):
try:
aktuell = aktuell[s]
except IndexError:
return standard
else:
return standard
return aktuell
# Verwendung
daten = {
"benutzer": {
"profil": {
"name": "Anna",
"hobbies": ["Lesen", "Programmieren"]
}
}
}
print(sicherer_zugriff(daten, "benutzer", "profil", "name"))
# Anna
print(sicherer_zugriff(daten, "benutzer", "profil", "hobbies", 0))
# Lesen
print(sicherer_zugriff(daten, "benutzer", "adresse", "stadt", standard="Unbekannt"))
# Unbekannt
Iteration ueber verschachtelte Strukturen
# Verschiedene Iterationsmuster
# 1. Verschachtelte Liste von Dicts
mitarbeiter = [
{
"name": "Anna",
"abteilung": "Entwicklung",
"projekte": ["Website", "App"]
},
{
"name": "Ben",
"abteilung": "Design",
"projekte": ["Website", "Logo"]
},
{
"name": "Clara",
"abteilung": "Entwicklung",
"projekte": ["App", "API", "Datenbank"]
}
]
# Alle Projekte aller Mitarbeiter
print("Alle Projekte pro Mitarbeiter:")
for ma in mitarbeiter:
print(f"\n {ma['name']} ({ma['abteilung']}):")
for projekt in ma["projekte"]:
print(f" - {projekt}")
# Alle einzigartigen Projekte
alle_projekte = set()
for ma in mitarbeiter:
alle_projekte.update(ma["projekte"])
print(f"\nAlle Projekte: {alle_projekte}")
# Mitarbeiter pro Projekt
from collections import defaultdict
projekt_teams = defaultdict(list)
for ma in mitarbeiter:
for projekt in ma["projekte"]:
projekt_teams[projekt].append(ma["name"])
print("\nTeams pro Projekt:")
for projekt, team in projekt_teams.items():
print(f" {projekt}: {', '.join(team)}")
# 2. Dict von Dicts mit Listen
bibliothek = {
"Fantasy": {
"Herr der Ringe": {"autor": "Tolkien", "bewertungen": [5, 4, 5, 5]},
"Harry Potter": {"autor": "Rowling", "bewertungen": [5, 5, 4, 5, 5]}
},
"Krimi": {
"Sherlock Holmes": {"autor": "Doyle", "bewertungen": [4, 5, 4]},
"Mord im Orient-Express": {"autor": "Christie", "bewertungen": [5, 4, 5, 4]}
}
}
print("\nBibliothek:")
for genre, buecher in bibliothek.items():
print(f"\n Genre: {genre}")
for titel, info in buecher.items():
bewertungen = info["bewertungen"]
schnitt = sum(bewertungen) / len(bewertungen)
print(f" '{titel}' von {info['autor']} "
f"-- Bewertung: {schnitt:.1f}/5 ({len(bewertungen)} Bewertungen)")
JSON-Daten verarbeiten
JSON (JavaScript Object Notation) ist das Standardformat fuer den Datenaustausch im Web. Python kann JSON direkt in Dictionaries und Listen umwandeln.
import json
# JSON-String in Python-Objekt umwandeln (Deserialisierung)
json_string = '''
{
"name": "Wetterdaten",
"standort": "Berlin",
"messungen": [
{"tag": "Montag", "temperatur": 15.2, "regen": false},
{"tag": "Dienstag", "temperatur": 18.7, "regen": false},
{"tag": "Mittwoch", "temperatur": 12.1, "regen": true},
{"tag": "Donnerstag", "temperatur": 14.5, "regen": false},
{"tag": "Freitag", "temperatur": 16.8, "regen": true}
]
}
'''
daten = json.loads(json_string)
print(type(daten)) # <class 'dict'>
# Auf die Daten zugreifen
print(f"Standort: {daten['standort']}")
print(f"Anzahl Messungen: {len(daten['messungen'])}")
for m in daten["messungen"]:
regen = "Regen" if m["regen"] else "Trocken"
print(f" {m['tag']}: {m['temperatur']}°C ({regen})")
# Durchschnittstemperatur
temps = [m["temperatur"] for m in daten["messungen"]]
print(f"\nDurchschnitt: {sum(temps) / len(temps):.1f}°C")
print(f"Maximum: {max(temps)}°C")
print(f"Minimum: {min(temps)}°C")
# Regentage
regentage = [m["tag"] for m in daten["messungen"] if m["regen"]]
print(f"Regentage: {', '.join(regentage)}")
JSON lesen und schreiben
import json
# Python-Objekt in JSON-String umwandeln (Serialisierung)
daten = {
"schueler": [
{"name": "Anna", "noten": [1.3, 2.0, 1.7]},
{"name": "Ben", "noten": [2.7, 3.0, 2.3]}
]
}
# Schöner JSON-String (mit Einrückung)
json_text = json.dumps(daten, indent=2, ensure_ascii=False)
print(json_text)
# In Datei speichern
with open("schueler.json", "w", encoding="utf-8") as datei:
json.dump(daten, datei, indent=2, ensure_ascii=False)
# Aus Datei laden
with open("schueler.json", "r", encoding="utf-8") as datei:
geladene_daten = json.load(datei)
print(geladene_daten["schueler"][0]["name"]) # Anna
Praxis: Schueler-Noten-System
def noten_system():
"""Ein vollständiges Schüler-Noten-Verwaltungssystem."""
schueler_db = {
"Anna Müller": {
"klasse": "10a",
"faecher": {
"Mathematik": [1.3, 2.0, 1.7, 1.0],
"Deutsch": [2.0, 1.7, 2.3],
"Englisch": [1.0, 1.3, 1.0, 1.7]
}
},
"Ben Schmidt": {
"klasse": "10a",
"faecher": {
"Mathematik": [2.7, 3.0, 2.3],
"Deutsch": [1.7, 2.0, 1.3],
"Englisch": [3.0, 2.7, 3.3]
}
},
"Clara Weber": {
"klasse": "10b",
"faecher": {
"Mathematik": [1.0, 1.3, 1.0],
"Deutsch": [1.3, 1.0, 1.7],
"Englisch": [1.7, 2.0, 1.3]
}
}
}
def zeugnis(name):
"""Erstellt ein Zeugnis für einen Schüler."""
if name not in schueler_db:
print(f"Schüler '{name}' nicht gefunden.")
return
schueler = schueler_db[name]
print(f"\n{'='*50}")
print(f" ZEUGNIS - {name}")
print(f" Klasse: {schueler['klasse']}")
print(f"{'='*50}")
gesamt_noten = []
for fach, noten in schueler["faecher"].items():
schnitt = sum(noten) / len(noten)
gesamt_noten.append(schnitt)
print(f" {fach:<15} {schnitt:.1f} ({len(noten)} Noten)")
gesamt = sum(gesamt_noten) / len(gesamt_noten)
print(f"{'─'*50}")
print(f" {'Gesamtdurchschnitt':<15} {gesamt:.2f}")
print(f"{'='*50}")
def note_hinzufuegen(name, fach, note):
"""Fügt eine Note für einen Schüler hinzu."""
if name not in schueler_db:
print(f"Schüler '{name}' nicht gefunden.")
return
if fach not in schueler_db[name]["faecher"]:
schueler_db[name]["faecher"][fach] = []
schueler_db[name]["faecher"][fach].append(note)
print(f"Note {note} in {fach} für {name} eingetragen.")
def rangliste(fach):
"""Erstellt eine Rangliste für ein bestimmtes Fach."""
ergebnisse = []
for name, daten in schueler_db.items():
if fach in daten["faecher"]:
noten = daten["faecher"][fach]
schnitt = sum(noten) / len(noten)
ergebnisse.append((name, schnitt))
ergebnisse.sort(key=lambda x: x[1])
print(f"\nRangliste {fach}:")
for platz, (name, schnitt) in enumerate(ergebnisse, 1):
print(f" {platz}. {name}: {schnitt:.2f}")
# System verwenden
print("--- Schüler-Noten-System ---")
# Zeugnisse erstellen
for name in schueler_db:
zeugnis(name)
# Neue Noten eintragen
note_hinzufuegen("Anna Müller", "Mathematik", 1.0)
note_hinzufuegen("Ben Schmidt", "Physik", 2.3)
# Ranglisten
rangliste("Mathematik")
rangliste("Deutsch")
noten_system()
Praxis: Kontaktliste
import json
def kontaktliste():
"""Kontaktverwaltung mit verschachtelten Datenstrukturen."""
kontakte = [
{
"name": "Anna Müller",
"telefon": {"privat": "0170-1234567", "arbeit": "030-9876543"},
"email": "anna@beispiel.de",
"adresse": {
"strasse": "Hauptstraße 1",
"plz": "10115",
"stadt": "Berlin"
},
"tags": ["Familie", "Arbeit"]
},
{
"name": "Ben Schmidt",
"telefon": {"privat": "0171-2345678"},
"email": "ben@beispiel.de",
"adresse": {
"strasse": "Nebenstraße 42",
"plz": "80331",
"stadt": "München"
},
"tags": ["Freund", "Sport"]
},
{
"name": "Clara Weber",
"telefon": {"privat": "0172-3456789", "arbeit": "040-1111111"},
"email": "clara@beispiel.de",
"adresse": {
"strasse": "Marktplatz 7",
"plz": "20095",
"stadt": "Hamburg"
},
"tags": ["Arbeit", "Schule"]
}
]
def kontakt_anzeigen(kontakt):
"""Zeigt alle Details eines Kontakts an."""
print(f"\n Name: {kontakt['name']}")
print(f" E-Mail: {kontakt['email']}")
print(f" Telefon:")
for typ, nummer in kontakt["telefon"].items():
print(f" {typ.capitalize()}: {nummer}")
adr = kontakt["adresse"]
print(f" Adresse: {adr['strasse']}, {adr['plz']} {adr['stadt']}")
print(f" Tags: {', '.join(kontakt['tags'])}")
def suche_nach_tag(tag):
"""Findet alle Kontakte mit einem bestimmten Tag."""
treffer = [k for k in kontakte if tag in k["tags"]]
if treffer:
print(f"\nKontakte mit Tag '{tag}':")
for k in treffer:
print(f" - {k['name']}")
else:
print(f"Keine Kontakte mit Tag '{tag}' gefunden.")
def suche_nach_stadt(stadt):
"""Findet alle Kontakte in einer bestimmten Stadt."""
treffer = [k for k in kontakte if k["adresse"]["stadt"].lower() == stadt.lower()]
if treffer:
print(f"\nKontakte in {stadt}:")
for k in treffer:
print(f" - {k['name']}: {k['telefon'].get('privat', 'Keine Nummer')}")
else:
print(f"Keine Kontakte in {stadt} gefunden.")
def als_json_speichern(dateiname):
"""Speichert die Kontakte als JSON-Datei."""
with open(dateiname, "w", encoding="utf-8") as f:
json.dump(kontakte, f, indent=2, ensure_ascii=False)
print(f"Kontakte in '{dateiname}' gespeichert.")
# Kontaktliste verwenden
print("--- Kontaktliste ---")
# Alle Kontakte anzeigen
for kontakt in kontakte:
kontakt_anzeigen(kontakt)
# Nach Tags suchen
suche_nach_tag("Arbeit")
suche_nach_tag("Familie")
# Nach Stadt suchen
suche_nach_stadt("Berlin")
suche_nach_stadt("Hamburg")
# Statistik
alle_staedte = {k["adresse"]["stadt"] for k in kontakte}
alle_tags = set()
for k in kontakte:
alle_tags.update(k["tags"])
print(f"\nStatistik:")
print(f" Kontakte: {len(kontakte)}")
print(f" Städte: {', '.join(sorted(alle_staedte))}")
print(f" Tags: {', '.join(sorted(alle_tags))}")
kontaktliste()
Flatten von verschachtelten Listen
Manchmal muss man eine verschachtelte Liste in eine flache Liste umwandeln:
# Einfaches Flatten (eine Ebene)
verschachtelt = [[1, 2, 3], [4, 5], [6, 7, 8, 9]]
# Methode 1: List Comprehension
flach = [element for unterliste in verschachtelt for element in unterliste]
print(flach) # [1, 2, 3, 4, 5, 6, 7, 8, 9]
# Methode 2: sum() Trick (nur fuer Listen!)
flach = sum(verschachtelt, [])
print(flach) # [1, 2, 3, 4, 5, 6, 7, 8, 9]
# Methode 3: itertools.chain
from itertools import chain
flach = list(chain.from_iterable(verschachtelt))
print(flach) # [1, 2, 3, 4, 5, 6, 7, 8, 9]
# Rekursives Flatten (beliebig tiefe Verschachtelung)
def flatten(liste):
"""Flacht eine beliebig tief verschachtelte Liste ab."""
ergebnis = []
for element in liste:
if isinstance(element, list):
ergebnis.extend(flatten(element)) # Rekursion
else:
ergebnis.append(element)
return ergebnis
tief = [1, [2, 3], [4, [5, 6, [7, 8]]], 9]
print(flatten(tief)) # [1, 2, 3, 4, 5, 6, 7, 8, 9]
# Generator-Variante (speichereffizient)
def flatten_generator(liste):
for element in liste:
if isinstance(element, list):
yield from flatten_generator(element)
else:
yield element
tief = [1, [2, [3, [4, [5]]]], 6]
print(list(flatten_generator(tief))) # [1, 2, 3, 4, 5, 6]
Tipps fuer Lesbarkeit
Bei verschachtelten Datenstrukturen ist Lesbarkeit besonders wichtig:
# SCHLECHT: Alles in einer Zeile
daten = {"schueler": [{"name": "Anna", "noten": {"mathe": [1,2,3], "deutsch": [2,1,3]}}, {"name": "Ben", "noten": {"mathe": [3,2,2], "deutsch": [1,2,1]}}]}
# GUT: Sauber eingerückt
daten = {
"schueler": [
{
"name": "Anna",
"noten": {
"mathe": [1, 2, 3],
"deutsch": [2, 1, 3]
}
},
{
"name": "Ben",
"noten": {
"mathe": [3, 2, 2],
"deutsch": [1, 2, 1]
}
}
]
}
# Tipp 1: Zwischenvariablen verwenden
# SCHWER LESBAR:
print(daten["schueler"][0]["noten"]["mathe"][2])
# BESSER:
erster_schueler = daten["schueler"][0]
mathe_noten = erster_schueler["noten"]["mathe"]
dritte_note = mathe_noten[2]
print(dritte_note)
# Tipp 2: Hilfsfunktionen schreiben
def get_noten(daten, schueler_index, fach):
"""Holt die Noten eines Schülers in einem Fach."""
try:
return daten["schueler"][schueler_index]["noten"][fach]
except (KeyError, IndexError):
return []
print(get_noten(daten, 0, "mathe")) # [1, 2, 3]
print(get_noten(daten, 5, "mathe")) # [] (Index existiert nicht)
# Tipp 3: pprint für schöne Ausgabe
from pprint import pprint
komplexe_daten = {
"server": {
"host": "localhost",
"port": 8080,
"features": ["auth", "logging", "caching"],
"database": {
"type": "postgresql",
"host": "db.beispiel.de",
"port": 5432
}
}
}
# Normale Ausgabe (schwer lesbar)
print(komplexe_daten)
# Schöne Ausgabe mit pprint
pprint(komplexe_daten, indent=2)
# Tipp 4: Datenklassen verwenden (ab Python 3.7)
from dataclasses import dataclass
from typing import List
@dataclass
class Schueler:
name: str
klasse: str
noten: List[float]
@property
def durchschnitt(self):
return sum(self.noten) / len(self.noten) if self.noten else 0
studenten = [
Schueler("Anna", "10a", [1.3, 2.0, 1.7]),
Schueler("Ben", "10b", [2.7, 3.0, 2.3]),
]
for s in studenten:
print(f"{s.name}: {s.durchschnitt:.2f}")
Uebungen
Uebung 1: Klassenarbeit auswerten
Erstelle ein Programm, das eine Klassenarbeit auswertet. Die Daten sind als verschachtelte Struktur gegeben.
klassenarbeit = {
"fach": "Mathematik",
"datum": "2026-02-10",
"ergebnisse": [
{"name": "Anna", "punkte": 45, "max_punkte": 50},
{"name": "Ben", "punkte": 32, "max_punkte": 50},
{"name": "Clara", "punkte": 48, "max_punkte": 50},
{"name": "David", "punkte": 28, "max_punkte": 50},
{"name": "Eva", "punkte": 41, "max_punkte": 50},
]
}
# Berechne fuer jeden Schueler:
# - Prozent erreicht
# - Note (ab 90%: 1, 80%: 2, 70%: 3, 60%: 4, 50%: 5, unter 50%: 6)
# Erstelle eine Rangliste und berechne den Klassendurchschnitt.
Uebung 2: Warenkorb
Erstelle ein Warenkorbsystem mit verschachtelten Datenstrukturen.
produkte = {
"A001": {"name": "Laptop", "preis": 999.99, "bestand": 10},
"A002": {"name": "Maus", "preis": 29.99, "bestand": 50},
"A003": {"name": "Tastatur", "preis": 79.99, "bestand": 30},
"A004": {"name": "Monitor", "preis": 349.99, "bestand": 15},
}
warenkorb = [] # Liste von {"produkt_id": ..., "menge": ...}
# Implementiere Funktionen:
# - zum_warenkorb(produkt_id, menge)
# - warenkorb_anzeigen()
# - gesamtpreis()
# - warenkorb_leeren()
Uebung 3: JSON-Daten analysieren
Analysiere die folgende JSON-Struktur und beantworte die Fragen im Code.
import json
bibliothek_json = '''
{
"bibliothek": "Stadtbibliothek Berlin",
"buecher": [
{"titel": "Python Grundlagen", "autor": "Max Muster", "jahr": 2023, "genre": "Sachbuch", "ausgeliehen": true},
{"titel": "Der Hobbit", "autor": "J.R.R. Tolkien", "jahr": 1937, "genre": "Fantasy", "ausgeliehen": false},
{"titel": "Clean Code", "autor": "Robert Martin", "jahr": 2008, "genre": "Sachbuch", "ausgeliehen": true},
{"titel": "Harry Potter", "autor": "J.K. Rowling", "jahr": 1997, "genre": "Fantasy", "ausgeliehen": false},
{"titel": "Algorithmen", "autor": "Thomas Cormen", "jahr": 2009, "genre": "Sachbuch", "ausgeliehen": false}
]
}
'''
daten = json.loads(bibliothek_json)
# 1. Wie viele Buecher gibt es insgesamt?
# 2. Welche Buecher sind ausgeliehen?
# 3. Wie viele Buecher gibt es pro Genre?
# 4. Welches ist das aelteste Buch?
# 5. Liste aller verfuegbaren (nicht ausgeliehenen) Buecher
Uebung 4: Verschachtelte Daten transformieren
Schreibe eine Funktion, die eine flache Liste von Datensaetzen in eine gruppierte, verschachtelte Struktur umwandelt.
# Eingabe: flache Liste
bestellungen = [
{"kunde": "Anna", "produkt": "Laptop", "preis": 999},
{"kunde": "Ben", "produkt": "Maus", "preis": 30},
{"kunde": "Anna", "produkt": "Tastatur", "preis": 80},
{"kunde": "Clara", "produkt": "Monitor", "preis": 350},
{"kunde": "Ben", "produkt": "Laptop", "preis": 999},
{"kunde": "Anna", "produkt": "Maus", "preis": 30},
]
# Erwartete Ausgabe: gruppiert nach Kunde
# {
# "Anna": {
# "bestellungen": [...],
# "gesamtbetrag": 1109
# },
# "Ben": { ... },
# "Clara": { ... }
# }
def gruppiere_bestellungen(bestellungen):
# Deine Loesung hier
pass
Pro-Tipp: Bei der Arbeit mit tief verschachtelten Daten (besonders JSON-APIs) lohnt sich ein Blick auf die Bibliothek jmespath fuer elegante Pfad-Abfragen:
# pip install jmespath
import jmespath
daten = {
"schueler": [
{"name": "Anna", "note": 1.3},
{"name": "Ben", "note": 2.7},
{"name": "Clara", "note": 1.0}
]
}
# Alle Namen extrahieren
namen = jmespath.search("schueler[*].name", daten)
print(namen) # ['Anna', 'Ben', 'Clara']
# Schueler mit Note besser als 2.0
gute = jmespath.search("schueler[?note < `2.0`].name", daten)
print(gute) # ['Anna', 'Clara']
Fuer einfachere Faelle reicht aber oft eine gut strukturierte Kombination aus Schleifen und Comprehensions voellig aus!