Listen, Dictionarys, Sets, Schleifen und Comprehensions
Wann du welchen der vier Container Pythons einsetzt, Schleifen und Bedingungen, Comprehensions und das Zählen von Wörtern in unordentlichen Tickets, um eine Top fünf zu finden, die jedes Mal gleich herauskommt.
Wie möchtest du lernen?
Das Problem, das wir lösen
Die Leitung des Supports will wissen, worüber sich die Kundschaft in den Tickets dieser Woche am meisten beschwert hat. Die Tickets sind unordentlicher Text — manche in Großbuchstaben, manche voller Satzzeichen, manche sagen dasselbe zweimal. Ein Teammitglied hat in fünf Minuten ein Skript geschrieben und eine Liste geschickt: the ganz oben, dann refund, dann Refund und refund. als getrennte Einträge.
Der zweite Lauf brachte ein anderes Problem: Eine kleine Änderung in der Reihenfolge der Tickets veränderte das fünfte Wort der Top fünf, obwohl sich bei keinem Wort die Anzahl geändert hatte. Niemand, der den Bericht las, konnte sagen, welche Version richtig war.
Die Antwort ist keine spezielle Bibliothek. Es sind Pythons vier grundlegende Container — Listen, Tupel, Dictionarys und Sets — sowie Schleifen und Bedingungen, richtig eingesetzt. Ein großer Teil der täglichen Arbeit eines KI-Engineers besteht genau darin: Text bereinigen, zählen, filtern und sortieren — so, dass bei gleicher Eingabe jedes Mal dasselbe Ergebnis herauskommt.
Am Ende dieses Kapitels kannst du
- Je nach Aufgabe Liste, Tupel, Dictionary oder Set wählen und begründen, warum
- Saubere Schleifen schreiben mit
for,while,if/elif/else,enumerateund.items() - Daten mit List-, Dictionary- und Set-Comprehensions filtern und umformen
- Wörter aus unordentlichem Text herauslösen und sie mit einem Dictionary und mit
Counterzählen - Wörter mit gleicher Anzahl nach einer expliziten Regel sortieren, damit das Ergebnis jedes Mal gleich ist
Was du vorher brauchst: pathlib, JSON/YAML-Config und Umgebungsvariablen — und die Fähigkeit, ein Skript mit uv run auszuführen.
Vier Container, vier Aufgaben
Zuerst die vier nebeneinander:
tickets = ["refund", "login", "refund", "billing"]
latest = ("T-1042", "refund", 3)
owners = {"refund": "Maya", "login": "Omar"}
seen = set(tickets)
print(tickets[0], tickets[-1], len(tickets))
print(latest[1])
print(owners["login"])
print(sorted(seen))
print("login" in seen, "shipping" in seen)refund billing 4
refund
Omar
['billing', 'login', 'refund']
True FalseJeder von ihnen verspricht etwas anderes, und du wählst nach diesem Versprechen:
- Liste (
[...]) — behält die Reihenfolge, erlaubt denselben Wert mehrfach und kann verändert werden. Für „eine Reihe von Dingen, die nacheinander kommen“: eine Liste von Tickets, ein Stapel Prompts. - Tupel (
(...)) — behält die Reihenfolge, lässt sich aber nach dem Erstellen nicht mehr verändern. Für wenige Werte, die zusammen einen Datensatz bilden, etwa("T-1042", "refund", 3)— ID, Kategorie, Priorität. Hier trägt die Position die Bedeutung. - Dictionary (
{key: value}) — einen Wert über seinen Schlüssel nachschlagen. „Wer besitzt welche Kategorie“, „wie oft kommt jedes Wort vor“ — überall, wo du von einer Sache zu einer anderen gehst. - Set (
set(...)oder{a, b}) — jeder Wert nur einmal, keine garantierte Reihenfolge. Für Fälle, in denen die Frage nur lautet „ist er drin“ oder „wie viele verschiedene Werte gibt es“.
sorted(seen) wird ausgegeben, weil die Reihenfolge eines ausgegebenen Sets nicht garantiert ist — sie kann bei einem Lauf so und beim nächsten anders aussehen. Hängt die Ausgabe eines Programms von der Reihenfolge eines Sets ab, ist diese Ausgabe ebenfalls nicht stabil.
inauf einer Liste prüft jedes Element nacheinander; auf einem Set oder Dictionary antwortet es fast sofort, egal ob es zehn oder zehn Millionen Elemente sind. Wenn du immer wiederif word in stop_wordsprüfst, solltestop_wordsein Set sein, nicht eine Liste. Warum das so ist und wie man den Unterschied misst, kommt später im Kurs.
Schleifen: Sag, was du durchläufst
Schleifen über Tupel und Dictionarys lesen sich am klarsten mit Unpacking — die Werte landen direkt in benannten Variablen:
ticket_id, category, priority = ("T-1042", "refund", 3)
print(ticket_id, category, priority)
owners = {"refund": "Maya", "login": "Omar"}
for category, owner in owners.items():
print(f"{category} -> {owner}")
for position, category in enumerate(["refund", "login"], start=1):
print(position, category)T-1042 refund 3
refund -> Maya
login -> Omar
1 refund
2 login.items() liefert bei jedem Durchlauf ein Paar (key, value), und enumerate gibt jedes Element zusammen mit seiner Position zurück — ohne Indizes mit range(len(...)) zu zählen. Seit Python 3.7 merkt sich ein Dictionary die Reihenfolge, in der seine Schlüssel eingefügt wurden, deshalb beginnt die Schleife über owners mit refund.
Was passiert, wenn du .items() vergisst?
owners = {"refund": "Maya", "login": "Omar"}
for category, owner in owners:
print(category, owner)Traceback (most recent call last):
File "main.py", line 2, in <module>
for category, owner in owners:
^^^^^^^^^^^^^^^
ValueError: too many values to unpack (expected 2)Wenn du direkt über ein Dictionary iterierst, bekommst du nur die Schlüssel. Der erste Schlüssel, "refund", ist ein String aus sechs Zeichen, und Python versucht, ihn auf zwei Variablen aufzuteilen — sechs Zeichen, zwei Variablen. Die Meldung wirkt merkwürdig, bis du dich erinnerst, dass ein String auch eine Sequenz ist.
if/elif/else hört bei der ersten Bedingung auf, die wahr ist, deshalb ist die Reihenfolge der Bedingungen die Logik:
latencies_ms = [120, 340, 95, 1800, 210, 2600]
for latency in latencies_ms:
if latency >= 2000:
label = "critical"
elif latency >= 1000:
label = "slow"
else:
label = "ok"
print(latency, label)120 ok
340 ok
95 ok
1800 slow
210 ok
2600 criticalSchreibst du die Bedingungen in umgekehrter Reihenfolge — erst>= 1000, dann>= 2000— gibt es keinen Fehler, aber2600wird zuslow, weil die erste Bedingung wahr ist und die Kette dort stoppt. Der Zweigcriticalläuft nie. Wenn du nach Schwellenwerten unterscheidest, steht die strengste Bedingung zuerst.
for läuft über eine bekannte Sammlung. while läuft, solange eine Bedingung gilt — wenn du im Voraus nicht weißt, wie oft es dauert. Daten Seite für Seite aus einer API zu holen ist der klassische Fall. Hier übernimmt ein Dictionary die Rolle der API:
pages = {1: ["t1", "t2"], 2: ["t3"], 3: []}
page = 1
collected = []
while True:
batch = pages[page]
if not batch:
break
collected.extend(batch)
page += 1
print(collected, "pages read:", page - 1)['t1', 't2', 't3'] pages read: 2Eine leere Seite bedeutet break. if not batch funktioniert, weil eine leere Liste falsy ist. Schreib in Schleifen wie dieser zuerst die Abbruchbedingung und den Rest danach — ein while True, bei dem das Stoppen vergessen wird, läuft für immer, und es gibt nicht einmal eine Fehlermeldung.
Comprehensions: eine Sammlung aus einer anderen
„Eine leere Liste, eine Schleife, ein if, ein append“ — dieses Vierzeilen-Muster ist so verbreitet, dass Python dafür eine einzeilige Form hat:
latencies_ms = [120, 340, 95, 1800, 210, 2600]
slow = [ms for ms in latencies_ms if ms >= 1000]
seconds = [ms / 1000 for ms in latencies_ms]
labels = {ms: ("slow" if ms >= 1000 else "ok") for ms in latencies_ms}
buckets = {ms // 1000 for ms in latencies_ms}
print(slow)
print(seconds)
print(labels)
print(sorted(buckets))[1800, 2600]
[0.12, 0.34, 0.095, 1.8, 0.21, 2.6]
{120: 'ok', 340: 'ok', 95: 'ok', 1800: 'slow', 210: 'ok', 2600: 'slow'}
[0, 1, 2]So liest du es: [ergebnis for element in sammlung if bedingung]. Der linke Teil sagt, was aus jedem Element gebaut wird; das nachgestellte if sagt, welche behalten werden. Dieselbe Form mit {key: value for ...} baut ein Dictionary, und {value for ...} ein Set — buckets enthält drei verschiedene Ein-Sekunden-Bereiche, jeden nur einmal.
Verwechsle die beiden Arten von if nicht. Das nachgestellte if ms >= 1000 ist ein Filter — ist es falsch, fällt das Element weg. "slow" if ms >= 1000 else "ok" ist eine Auswahl — jedes Element bleibt, und sein Wert ist einer von beiden. Deshalb hat labels alle sechs.
Eine Comprehension ist dafür da, eine neue Sammlung zu bauen. Wenn du nur etwas ausgeben oder in eine Datei schreiben willst — wenn das Ergebnis sowieso weggeworfen würde —, schreib eine gewöhnliche for-Schleife. Und eine dreifach verschachtelte Comprehension passt vielleicht in eine Zeile, aber eine fünfzeilige Schleife ist für eine Kollegin oder einen Kollegen oft leichter zu lesen.
Wörter zählen: von Hand, dann mit Counter
Fast jeder erste Versuch, mit einem Dictionary zu zählen, sieht so aus:
words = ["refund", "late", "refund", "login", "refund", "late"]
counts = {}
for word in words:
counts[word] += 1Traceback (most recent call last):
File "main.py", line 5, in <module>
counts[word] += 1
~~~~~~^^^^^^
KeyError: 'refund'counts[word] += 1 bedeutet counts[word] = counts[word] + 1 — und das Lesen von counts[word] auf der rechten Seite zeigt, dass der Schlüssel "refund" noch nicht existiert. Ein Wort, das zum ersten Mal vorkommt, braucht einen Startwert. .get(key, 0) liefert genau das:
words = ["refund", "late", "refund", "login", "refund", "late"]
counts = {}
for word in words:
counts[word] = counts.get(word, 0) + 1
print(counts){'refund': 3, 'late': 2, 'login': 1}Die Aufgabe ist so häufig, dass die Standardbibliothek dafür einen Typ mitbringt — collections.Counter, eine Art Dictionary:
from collections import Counter
words = ["refund", "late", "login", "refund", "login", "late", "slow"]
counts = Counter(words)
print(counts)
print(counts.most_common(2))
print(counts["missing"])Counter({'refund': 2, 'late': 2, 'login': 2, 'slow': 1})
[('refund', 2), ('late', 2)]
0Wenn du aus einem Counter einen fehlenden Schlüssel liest, bekommst du 0 statt eines KeyError — genau richtig zum Zählen. Schau aber auf most_common(2): refund, late und login haben alle eine Anzahl von 2, und zurück kamen die ersten beiden. Warum fiel login heraus? Weil most_common bei gleicher Anzahl die Reihenfolge behält, in der die Wörter zum ersten Mal vorkamen. login kam in der Liste erst als Drittes, also verlor es. Änderst du die Reihenfolge der Tickets, ändert sich auch das Ergebnis — das Rätsel vom Anfang des Kapitels.
Text bereinigen: Was sind wirklich Wörter?
split() trennt nur an Leerzeichen:
text = "Refund not received. REFUND please! Login fails; login page is slow."
print(text.split())
print(text.lower().split())['Refund', 'not', 'received.', 'REFUND', 'please!', 'Login', 'fails;', 'login', 'page', 'is', 'slow.']
['refund', 'not', 'received.', 'refund', 'please!', 'login', 'fails;', 'login', 'page', 'is', 'slow.'].lower() hat den Unterschied zwischen Groß- und Kleinschreibung erledigt, aber received., please! und slow. tragen immer noch Satzzeichen — und beim Zählen sind slow. und slow zwei verschiedene Wörter. Hier hilft ein regulärer Ausdruck: Statt zu sagen, was man wegwerfen soll, sagt man, wie ein Wort aussieht:
import re
text = "Refund not received. REFUND please! Login fails; login page is slow. Can't pay."
words = re.findall(r"[a-z']+", text.lower())
print(words)['refund', 'not', 'received', 'refund', 'please', 'login', 'fails', 'login', 'page', 'is', 'slow', "can't", 'pay'][a-z']+ bedeutet „ein oder mehrere englische Kleinbuchstaben oder Apostrophe“. re.findall liefert jede Stelle im Text zurück, auf die das Muster passt, und alles andere — Punkte, Kommas, Ziffern — fällt weg. can't bleibt ein Wort.
Dieses Muster hat eine Lücke: Schreibt jemand'invalid token', wird das erste Wort zu'invalid— mit dem Anführungszeichen daran. Das nächste Beispiel zieht das Muster enger, sodass ein Apostroph nur zwischen zwei Buchstaben stehen kann. Und denk daran:[a-z]steht nur für englische Buchstaben; Text in anderen Schriften braucht ein anderes Muster.
Gleiche Anzahlen: die Sortierregel selbst festlegen
Um Anzahlen in eine Rangliste zu verwandeln, musst du sortieren. Drei Wege, an einem Dictionary, in dem refund und login beide eine Anzahl von 3 haben:
counts = {"refund": 3, "late": 2, "login": 3, "slow": 1}
print(sorted(counts, reverse=True))
print(sorted(counts.items(), key=lambda item: item[1], reverse=True))
print(sorted(counts.items(), key=lambda item: (-item[1], item[0])))['slow', 'refund', 'login', 'late']
[('refund', 3), ('login', 3), ('late', 2), ('slow', 1)]
[('login', 3), ('refund', 3), ('late', 2), ('slow', 1)]Die erste Zeile ist die gefährlichste, weil sie vernünftig aussieht. Ein Dictionary zu sortieren sortiert seine Schlüssel, nicht seine Werte — das ist also alphabetisch rückwärts und hat mit den Anzahlen nichts zu tun. slow kam nur einmal vor und steht trotzdem ganz oben. Kein Fehler.
Die zweite Zeile sortiert nach Anzahl. Aber welches kommt zuerst, refund oder login? Pythons sorted ist „stabil“ — Elemente mit gleichem Schlüssel behalten die Reihenfolge, die sie in der Eingabe hatten. refund wurde zuerst ins Dictionary eingefügt, also steht es vorn. Anders gesagt: Das Ergebnis hängt davon ab, in welcher Reihenfolge die Daten ankamen.
Die dritte Zeile formuliert die Regel selbst. key gibt ein Tupel zurück, und Tupel werden Element für Element verglichen: zuerst -item[1] — die negative Anzahl, also kommen größere Anzahlen zuerst — und bei Gleichstand item[0], das Wort selbst, alphabetisch. Jetzt ist das Ergebnis dasselbe, egal in welcher Reihenfolge die Eingabe ankommt. reverse=True ist nicht nötig, denn das Minuszeichen kehrt die Anzahl-Reihenfolge bereits um, während die alphabetische Reihenfolge unverändert bleibt.
Überall dort, wo Ergebnisse verglichen werden — Berichte, Tests, Evaluierungen —, gib eine explizite Regel für die Reihenfolge gleicher Werte an. Sonst unterscheiden sich der Bericht von heute und der von morgen genau dort, wo sich die Daten selbst nicht geändert haben.
Ein vollständiges Beispiel
Jetzt alles zusammen: die fünf häufigsten Wörter in den Tickets. Stoppwörter — Wörter wie the und and, die in jedem Text vorkommen, aber nichts aussagen — fliegen raus, Wörter mit zwei Buchstaben auch, und Gleichstände werden alphabetisch aufgelöst. top_words.py:
import re
from collections import Counter
STOP_WORDS = {
"a", "and", "for", "i", "is", "it", "my", "not", "of", "on", "the", "to", "was", "with",
}
TICKETS = [
"Refund not received for order 1182. I was charged twice!",
"The app is slow and the login page freezes.",
"Charged twice again. Please refund the second charge.",
"Login fails with 'invalid token' on my phone.",
"Still waiting on my refund, it was promised last week.",
"App slow after the update; login takes a minute.",
]
def tokenize(text: str) -> list[str]:
return re.findall(r"[a-z]+(?:'[a-z]+)?", text.lower())
def top_words(texts: list[str], n: int = 5) -> list[tuple[str, int]]:
counts = Counter(
word
for text in texts
for word in tokenize(text)
if word not in STOP_WORDS and len(word) > 2
)
ranked = sorted(counts.items(), key=lambda item: (-item[1], item[0]))
return ranked[:n]
def print_ranking(ranking: list[tuple[str, int]]) -> None:
if not ranking:
print("no words to rank")
return
width = max(len(word) for word, _ in ranking)
for rank, (word, count) in enumerate(ranking, start=1):
print(f"{rank}. {word:<{width}} {count} {'#' * count}")
if __name__ == "__main__":
print_ranking(top_words(TICKETS))
print_ranking(top_words([]))uv run top_words.py1. login 3 ###
2. refund 3 ###
3. app 2 ##
4. charged 2 ##
5. slow 2 ##
no words to rankDie Entscheidungen dahinter:
Das Wortmuster [a-z]+(?:'[a-z]+)?. Ein oder mehr Buchstaben, dann optional ein Apostroph und weitere Buchstaben. can't bleibt ein Wort, aber das Anführungszeichen um 'invalid token' wird nicht mehr Teil eines Wortes. (?:...) ist eine Gruppe, die nicht erfasst wird — mit einem einfachen (...) würde re.findall nur den Teil der Gruppe zurückgeben statt des ganzen Wortes.
Stoppwörter sind ein Set. Jedes Wort wird mit word not in STOP_WORDS geprüft; bei einem Set ist diese Prüfung nahezu sofort, egal wie lang die Liste wird.
Counter wird direkt von einem Generator gefüttert. Zwei for und ein if ergeben einen einzigen Strom — jedes Wort jedes Tickets, das den Filter passiert. Es wird keine große Zwischenliste aller Wörter gebaut. Die beiden for stehen in derselben Reihenfolge wie gewöhnlich verschachtelte Schleifen: die äußere zuerst.
Eine explizite Tie-Break-Regel. login und refund haben beide 3; app, charged, slow und twice haben alle 2. Die alphabetische Reihenfolge entschied, wer den fünften Platz bekam, deshalb fiel twice heraus. Die Regel ist nicht perfekt — twice wurde nicht aus Gründen der Wichtigkeit weggelassen —, aber sie ist festgelegt und jedes Mal dieselbe. Fragt jemand, der den Bericht liest, nach dem Warum, gibt es eine Antwort.
Leere Eingaben bewusst behandelt. max() auf einer leeren Sammlung wirft ValueError: max() iterable argument is empty. Eine ruhige Woche ohne Tickets ist normal, kein Fehler — deshalb prüft print_ranking zuerst, ob die Rangliste leer ist. Die zweite Ausgabezeile zeigt genau das.
Berechnen und Anzeigen getrennt. top_words gibt eine Liste zurück und gibt nichts aus; print_ranking gibt nur aus. So lassen sich dieselben Anzahlen aus einem Test, einer API oder einem Dashboard verwenden. {word:<{width}} richtet jedes Wort linksbündig in einem Feld so breit wie das längste aus, damit die Spalte mit den Anzahlen gerade untereinander steht.
Eine Einschränkung: charged und charge sind hier zwei getrennte Wörter. Die Formen eines Wortes zusammenzuführen ist ein eigenes Problem, und KI-Systeme gleichen meist nach Bedeutung ab statt durch Zählen von Wörtern — dieser Ansatz kommt später im Kurs. Aber auch dort sind Text bereinigen, filtern und in stabiler Reihenfolge sortieren — die Arbeit dieses Kapitels — die ersten Schritte.
Wenn es schiefgeht
KeyError: 'refund' counts[word] += 1 für einen Schlüssel, der im Dictionary noch nicht existiert. Schreib counts[word] = counts.get(word, 0) + 1 oder nimm collections.Counter.
ValueError: too many values to unpack (expected 2) Der Code schreibt for key, value in d: über ein Dictionary. Wenn du direkt über ein Dictionary iterierst, bekommst du nur Schlüssel; schreib d.items(), um Paare zu erhalten.
TypeError: unhashable type: 'list' Eine Liste wurde in ein Set gelegt oder als Dictionary-Schlüssel verwendet. Set-Elemente und Dictionary-Schlüssel müssen Dinge sein, die sich nicht verändern können. Nimm stattdessen ein Tupel: seen.add(("refund", "late")).
RuntimeError: dictionary changed size during iteration Während der Schleife über ein Dictionary wurden Schlüssel gelöscht oder hinzugefügt. Bau ein neues Dictionary, statt zu löschen: counts = {word: n for word, n in counts.items() if n >= 2}.
AttributeError: 'tuple' object has no attribute 'append' Ein Tupel lässt sich nach dem Erstellen nicht verändern. Wenn die Werte wirklich wachsen und schrumpfen, hätte es eine Liste sein müssen; ist das Tupel ein Datensatz, baust du ein neues Tupel mit dem neuen Wert.
ValueError: max() iterable argument is empty max() oder min() auf einer leeren Sammlung. Prüfe vorher, ob sie leer ist, oder gib einen Standardwert an: max(lengths, default=0).
Schritt 4 von 6 — Vorhersagen
Prüfe dein Verständnis
Ein Teammitglied holt aus einer Sammlung von Anzahlen „das häufigste Wort“. Was wird ausgegeben?
counts = {"refund": 5, "slow": 1, "login": 3}
print(sorted(counts, reverse=True)[0])- A`refund`
- B`('refund', 5)`
- C`slow`
- D`5`
label(2600) sollte "critical" zurückgeben, gibt aber "slow" zurück — ohne Fehler. Wo steckt der Fehler?
def label(latency_ms):
if latency_ms >= 1000:
return "slow"
elif latency_ms >= 2000:
return "critical"
return "ok"
print(label(2600))- ADie Reihenfolge der Bedingungen: `>= 1000` ist zuerst wahr und die Kette stoppt, sodass `>= 2000` nie erreicht wird — die strengste Bedingung muss zuerst stehen
- BVor `return "ok"` fehlt ein `else:`
- CDie zweite Bedingung muss `if` statt `elif` verwenden
- D`2600` ist eine ganze Zahl, also muss es vor dem Vergleich mit `>=` mit `float()` umgewandelt werden
Eine Pipeline prüft für jedes von einer Million Wörtern, ob es eines von 300 Stoppwörtern ist. Welcher Container soll die Stoppwörter enthalten?
- AEin String, in dem alle Wörter zu einem langen Text zusammengefügt sind
- BEin Tupel, weil sich Stoppwörter nicht ändern
- CEin Set, weil eine `in`-Prüfung unabhängig von der Größe nahezu sofort ist
- DEine Liste, weil sie alphabetisch sortiert gehalten werden kann
Spielen ist Teil von Pro
+30 XP warten
Spiele dieses Kapitel mit Pro
Lesen ist kostenlos, und das ganze Kapitel ist offen. Die ersten 5 Kapitel jedes kostenlosen Kurses kannst du kostenlos spielen. Ab Kapitel 6 gehören Fragen beantworten, XP sammeln und deine Serie ausbauen zu Pro.
Spielen mit Pro freischaltenJetzt bist du dran
Finde jetzt die häufigsten Wörter pro Kategorie. Kopiere in einer Datei namens categories.py das STOP_WORDS und tokenize aus dem Kapitel und füge diese Tickets hinzu:
TICKETS = [
("billing", "Charged twice for one order."),
("billing", "Refund for the double charge, please."),
("login", "Login fails on the new phone."),
("billing", "Still no refund after the charge."),
("login", "Password reset email never arrives."),
("login", "Login page shows a blank screen."),
]Schreib dann Code, der Folgendes erfüllt:
- Jede Kategorie hat ihre eigenen Anzahlen — ein Dictionary, dessen Schlüssel die Kategorienamen sind und dessen Werte der
Counterder jeweiligen Kategorie ist (Tipp:dict.setdefaultundCounter.update) - Stoppwörter und Wörter mit zwei oder weniger Buchstaben werden nicht gezählt
- Jede Kategorie zeigt ihre beiden häufigsten Wörter, mit höheren Anzahlen zuerst und alphabetischer Reihenfolge bei Gleichstand
- Die Kategorien werden alphabetisch ausgegeben, egal in welcher Reihenfolge die Tickets kommen
uv run categories.py soll genau diese Ausgabe liefern:
billing charge=2, refund=2
login login=2, arrives=1Kehre danach die Liste TICKETS um (TICKETS[::-1]) und führe das Programm erneut aus — ändert sich die Ausgabe überhaupt? Wenn ja, welche Bedingung ist dann nicht erfüllt? Entferne zum Schluss den Tie-Break und sortiere nur nach Anzahl: Was ist das zweite Wort für login, und bleibt es dasselbe, wenn du die Reihenfolge umkehrst?
Schritt 6 von 6
Herausforderung — das Kapitel-Quiz
Zehn Fragen von leicht bis schwer. Die letzten sind absichtlich knifflig.
Mit Pro spielen