Listen: append, remove und sort
Kurz gesagt: Eine Liste ist eine Collection, die wächst und schrumpft: append hängt hinten an, remove nimmt ein Element heraus, ohne eine Lücke zu lassen, und sort bringt sie in Reihenfolge.
Problem
Der Warenkorb ist voll
Du schreibst den Warenkorb eines Onlineshops und hältst die Artikel in einer Liste, wie in der Lektion über Arrays: jeder Artikel an seinem Index. Aber über das Ende hinaus kannst du nicht schreiben: cart[3] = "Butter" bricht das Programm mit IndexError: list assignment index out of range ab. Für einen vierten Artikel legst du also eine neue, längere Liste an. Und nimmt der Kunde einen Artikel heraus, bleibt eine Lücke:
cart = ["Brot", "Milch", "Kaffee"]
# Ein vierter Artikel: cart[3] = "Butter" bricht mit IndexError ab,# also legen wir eine neue, längere Liste an.cart = cart + ["Butter"]
# Der Kunde nimmt die Milch heraus.cart[1] = None
for item in cart: print(item)BrotNoneKaffeeButterNone überspringen. Und die Zahl der Artikel ist nicht mehr len(cart).Das ist viel Code für etwas, das jeder Shop ständig macht.
Die Idee
append und remove: Die Liste kümmert sich selbst
Die Liste hat Methoden, die das für dich erledigen. Innen hält sie die Elemente immer noch in einem Array, aber das Kopieren und Verschieben macht sie selbst. Eine Collection, die so wächst und schrumpft, heißt Liste:
cart = []cart.append("Brot")cart.append("Milch")cart.append("Kaffee")cart.append("Butter")cart.remove("Milch")print(cart)print("Artikel:", len(cart))['Brot', 'Kaffee', 'Butter']Artikel: 3appendhängt hinten an.removeentfernt das Element mit diesem Wert und schließt die Lücke: „Kaffee“ rückt auf den Platz von „Milch“. Steht der Wert mehrmals darin, entfernt es den ersten.len(cart)ist die Zahl der Elemente gerade jetzt.printgibt die ganze Liste in eckigen Klammern aus, den Text in Anführungszeichen.
So sieht es in der Liste aus. Wie viele Plätze das Array hat, wählst nicht du. Das macht CPython, das Programm, das deinen Code ausführt. Eine Liste mit 4 Artikeln, die im Code steht, hat genau 4 Plätze, also ist das Array beim fünften voll:
cart = ["Brot", "Milch", "Kaffee", "Butter"]cart.append("Käse")cart.remove("Milch")print(cart)print("Artikel:", len(cart))Schritt für Schritt, in Worten
- cart zeigt auf ein Listenobjekt. Darin liegen ein Zähler ob_size und ein Array ob_item mit 4 Plätzen.
- Die Artikel aus dem Code füllen die Plätze nacheinander. Das Array ist voll: 4 von 4.
- Es ist kein Platz mehr. append reserviert ein Array mit 8 Plätzen, und die Elemente kommen hinein.
- ob_item zeigt jetzt auf das neue Array. „Käse“ kommt auf den ersten freien Platz.
- remove entfernt „Milch“, und alles danach rückt einen Platz nach links. Es bleibt keine Lücke.
- Von außen siehst du nur eine Liste mit vier Artikeln. Wie viele Plätze sie innen hat, entscheidet CPython: Die Sprache verspricht es nicht.
Die Idee
Was in eine Liste passt
Eine Liste fragt nicht, was du hineinlegst. Text und eine Zahl können nebeneinander stehen:
cart = []cart.append("Brot")cart.append(5)print(cart)['Brot', 5]Das sieht praktisch aus, aber der Fehler zeigt sich später, dort, wo du Text erwartest. Zum Beispiel in einer Schleife, die die Artikel in Großbuchstaben ausgibt:
cart = ["Brot", 5]for item in cart: print(item.upper())AttributeError: 'int' object has no attribute 'upper'„Brot“ wird ausgegeben, und bei der Zahl bricht das Programm ab. Eine Liste hält also eine Art von Dingen: nur Artikel, nur Preise.
Das kannst du mit einem Typhinweis festhalten: list[str] bedeutet „eine Liste mit Text“.
cart: list[str] = []cart.append("Brot")cart.append(5)print(cart)['Brot', 5]Python prüft den Hinweis nicht, während das Programm läuft: Die Zahl kommt trotzdem hinein. Dein Editor und Werkzeuge wie mypy prüfen ihn, bevor du das Programm startest. Diese Lektion hat keine Hinweise, aber in fremdem Code wirst du sie sehen.
Die Idee
Indizes: [i], insert, index, in
Eine Liste hat Indizes wie ein Array, von 0 bis len(tasks) - 1, und du schreibst sie mit denselben [ ]:
tasks = ["Rechnung März", "Bank anrufen", "Lagerbericht"]
print(tasks[0])tasks[1] = "Termin bei der Bank"tasks.insert(0, "Kaffee mit dem Team")print(tasks)print(tasks.index("Lagerbericht"))print("Bank anrufen" in tasks)Rechnung März['Kaffee mit dem Team', 'Rechnung März', 'Termin bei der Bank', 'Lagerbericht']3Falsetasks[i]liest, undtasks[i] = xersetzt.insert(i, x)fügt bei Indexiein und schiebt den Rest nach rechts.index(x)sucht und gibt den Index zurück, undx in taskssagt nur, ob es darin ist.
Genauer, für Neugierige
- Ein Index außerhalb der Liste bricht das Programm ab. Ein negativer Index zählt von hinten:
tasks[-1]ist die letzte Aufgabe. Undindexfür etwas, das nicht darin ist, bricht das Programm auch ab, also frag zuerst mitin:
tasks = ["Rechnung März", "Bank anrufen", "Lagerbericht"]try: print(tasks[3])except IndexError as e: print(f"IndexError: {e}")print(tasks[-1])try: tasks.index("Gehälter")except ValueError as e: print(f"ValueError: {e}")IndexError: list index out of rangeLagerberichtValueError: 'Gehälter' is not in listinundindexvergleichen mit==. Darum finden sie gleichen Text, nicht nur dasselbe Objekt.- Einfügen und Entfernen vorne sind in einer großen Liste langsam: Jedes Element nach dem Index rückt einen Platz weiter. Bei einer Million Elementen sind das eine Million Verschiebungen.
Probier es aus
Wer ist dran?
Die Liste der Patienten, die beim Arzt warten. Jonas geht hinein, und Anna hat einen Termin, darum bekommt sie den zweiten Platz.
Was gibt das Programm aus?
waiting = ["Jonas", "Maria", "Peter"]waiting.pop(0)waiting.insert(1, "Anna")print(waiting, len(waiting))pop(0) entfernt Jonas, und Maria wird Erste, bei Index 0. insert(1, "Anna") fügt Anna bei Index 1 ein und schiebt Peter nach rechts. Drei bleiben übrig.
Die Idee
Die Elemente durchlaufen
Eine Liste durchläufst du mit for, wenn du nur die Elemente brauchst. Brauchst du auch die Nummer, gibt es enumerate:
cart = ["Brot", "Kaffee", "Butter"]
for item in cart: print(f"- {item}")for number, item in enumerate(cart, start=1): print(f"{number}. {item}")- Brot- Kaffee- Butter1. Brot2. Kaffee3. Butterenumerate(cart, start=1) gibt bei jedem Schritt zwei Werte: die Nummer und das Element. Ohne start=1 beginnen die Nummern bei 0, wie die Indizes. Du kannst auch einen Index nehmen, wie in der Lektion über Arrays, mit for i in range(len(cart)), aber enumerate ist in Python der übliche Weg.
Genauer, für Neugierige
- Entferne keine Elemente aus einer Liste, während du sie mit
fordurchläufst. Das Programm bricht nicht ab, aber es überspringt Elemente:
cart = ["Brot", "Brot", "Milch"]for item in cart: if item == "Brot": cart.remove(item)print(cart)['Brot', 'Milch']Das zweite „Brot“ ist geblieben. remove hat alles nach links verschoben, und die Schleife ging beim nächsten Index weiter und hat es nie gesehen. Es gibt keinen Fehler, darum ist so ein Versäumnis schwer zu finden.
- Wenn du entfernen musst, durchläufst du mit einem Index von hinten nach vorne. So verschiebt das Entfernen nicht die Elemente, die du noch nicht geprüft hast:
cart = ["Brot", "Brot", "Milch"]for i in range(len(cart) - 1, -1, -1): if cart[i] == "Brot": cart.pop(i)print(cart)['Milch']Die Idee
Zahlen in einer Liste
Eine Liste mit Noten ist wie eine Liste mit Text. Die Zahl liegt so in der Liste, wie sie ist:
scores = [85, 64, 91]
total = 0for score in scores: total += scoreprint("Durchschnitt:", total / len(scores))print("Durchschnitt:", sum(scores) / len(scores))Durchschnitt: 80.0Durchschnitt: 80.0/gibt eine Kommazahl, darum ist der Durchschnitt80.0, nicht 80.sumaddiert alle Zahlen der Liste. Beide Zeilen berechnen dasselbe.
Genauer, für Neugierige
- In Python ist auch eine Zahl ein Objekt. Für kleine Zahlen, von -5 bis 256, hält Python fertige Objekte bereit, für größere erzeugt es neue. Darum gibt
is, das fragt „ist es dasselbe Objekt?“, verschiedene Antworten:
a = int("256")b = int("256")c = int("257")d = int("257")print(a is b)print(c is d)print(c == d)TrueFalseTrueVergleiche Zahlen und Text mit ==: Es fragt, ob die Werte gleich sind. is ist für None: if found is None.
Probier es aus
Finde den Fehler
Ein Theater hält die belegten Plätze in einer Liste. Ein Kunde gibt Platz 2 zurück, und das Programm soll [12, 7, 5] ausgeben. Stattdessen gibt es [12, 2, 5] aus. In welcher Zeile steckt der Fehler?
Wähle die Zeile mit dem Fehler.
pop(i) entfernt nach Index: pop(2) entfernt das Element bei Index 2, also Platz 7. remove entfernt nach Wert: seats.remove(2). Bei einer Liste mit Text verwechselt man die beiden Methoden kaum, aber bei Zahlen sind Index und Wert beide Zahlen.Die Idee
Sortieren und eine Liste, die sich nicht ändert
sort() sortiert die Liste an Ort und Stelle: Text alphabetisch, Zahlen nach Größe. sorted(...) rührt nichts an. Es gibt eine neue, sortierte Liste zurück.
cities = ["Hamburg", "Berlin", "Dresden"]cities.sort()print(cities)
prices = (30, 5, 12)print(sorted(prices))['Berlin', 'Dresden', 'Hamburg'][5, 12, 30]Die Preise stehen in runden Klammern: (30, 5, 12). Das ist ein Tupel, eine Liste, die unveränderlich ist. Du kannst es lesen und durchlaufen, aber darin nichts hinzufügen, entfernen oder sortieren:
days = ("Mo", "Di", "Mi")days.append("Do")AttributeError: 'tuple' object has no attribute 'append'Darum werden die Preise oben mit sorted sortiert: Es gibt eine neue Liste zurück, und das Tupel bleibt gleich. Ein Tupel ist für Dinge, die sich nicht ändern: die Wochentage, die zwei Koordinaten eines Punkts.
Genauer, für Neugierige
- Text wird nach den Codes seiner Zeichen sortiert. Großbuchstaben kommen vor Kleinbuchstaben, darum kommt „Traube“ vor „apfel“:
fruit = ["apfel", "Birne", "banane", "Traube"]fruit.sort()print(fruit)['Birne', 'Traube', 'apfel', 'banane']- Wie du eigene Objekte sortierst, zum Beispiel Produkte nach Preis, siehst du in der Lektion „Klassen in Klassen“.
Übung
Listen in Klassen
_ vorne („von außen nicht anfassen“), und der Code unter den Klassen ruft nur ihre Methoden auf.1. Ein Bücherregal. Eine Klasse BookShelf mit einer Methode add_book(title), die das Buch ans Ende stellt, und take_book(), die das erste Buch zurückgibt und entfernt (oder None, wenn das Regal leer ist). Füge count() und __str__() hinzu. Füge „Unter dem Joch“, „Tabak“ und „Der eiserne Leuchter“ hinzu, nimm ein Buch und gib den Rest aus.
Genommen: Unter dem Joch2 übrig: ['Tabak', 'Der eiserne Leuchter']2. Ein Ereignisprotokoll. Eine Klasse Event mit einem Datum und einer Beschreibung und eine Klasse EventLog mit den Methoden add_event(date, description) und get_events_between(start, end), die eine Liste der Ereignisse zwischen den beiden Daten zurückgibt, einschließlich. Die Daten sind Text in der Form 2026-03-31. In dieser Form sortiert sich der Text genauso wie die Daten, darum vergleichen <= und >= sie richtig. Füge vier Ereignisse hinzu: 2026-01-15 „Jahresinventur“, 2026-03-31 „Bericht erstes Quartal“, 2026-05-20 „Neuer Kaffeelieferant“, 2026-09-01 „Neues Schuljahr“. Gib die vom 2026-03-01 bis 2026-06-30 aus.
2026-03-31 Bericht erstes Quartal2026-05-20 Neuer Kaffeelieferant3. Ein Notizbuch. Eine Klasse Note mit einem Titel und einem Inhalt und eine Klasse Notebook mit den Methoden add_note, find_note(title) (gibt die Notiz oder None zurück), delete_note(title) (gibt True zurück, wenn es etwas gelöscht hat) und count(). Füge die Notizen „OOP“, „Collections“ und „SQL“ hinzu, finde „Collections“, lösche „OOP“ und prüfe, dass sie weg ist.
Collections: die Liste wächst von selbstGelöscht: OOPNotizen: 2Es gibt keine Notiz OOP.4. Kopfrechnen. Eine Klasse Question mit einem Text und der richtigen Antwort und eine Klasse MathGame mit einer Liste von Fragen, einer Methode add_question und einer Methode start(). start stellt die Fragen nacheinander, liest die Antwort und sagt am Ende, wie viele richtig waren. Die Fragen sind 2 + 2, 3 * 4 und 15 - 9.
41272 + 2 = Richtig!3 * 4 = Richtig!15 - 9 = Falsch, die Antwort ist 6.Ergebnis: 2 von 3Weitere Aufgaben
- Keine Wiederholungen. Lies 6 Namen ein und sammle sie in einer Liste, wobei du die überspringst, die schon darin sind. Für die Eingabe Jonas, Maria, Jonas, Anna, Maria, Peter ist die Ausgabe
['Jonas', 'Maria', 'Anna', 'Peter']. - Der teuerste Artikel. Eine Liste enthält Preise. Finde den höchsten und seinen Index, ohne
max. - Die Liste umdrehen. Schreib eine Funktion, die eine neue Liste mit denselben Elementen in umgekehrter Reihenfolge zurückgibt. Ändere das Original nicht.
- Eine Einkaufsliste. Lies die Befehle
add milk,remove milk,listundendund halte die Liste zwischen ihnen. Der Befehl, einen Artikel zu entfernen, der nicht darin ist, sagt „Kein solcher Artikel.“
Test
Teste dich
Verwandte Lektionen
Abschnitt „Verwandte Lektionen“- Baut auf: Polymorphie · Interfaces als abstrakte Klassen · Exceptions · Strings
- Geht weiter in: Stack, Queue und verkettete Liste · dict und set · Hashcodes und Hashfunktionen · Klassen und Daten in Klassen
- Aufgaben zum Thema: Collections