für die Programmierung. Was genau ist eine Menge also? Eine Menge ist eine ungeordnete Sammlung eindeutiger Elemente. Zerlegen wir diese Definition in ihre Bestandteile.
Sammlung
Eine Menge ist eine Sammlung von Elementen wie eine Liste oder ein Tupel. Die Sammlung besteht entweder aus primitiven (Integer, Floats, Strings) oder aus komplexen Elementen (Objekte, Tupel). Allerdings müssen alle Datentypen Hash-fähig sein, was bedeutet, dass ihnen ein Hash-Wert zugeordnet ist. Der Hash-Wert eines Objekts ändert sich nie und wird dazu verwendet, um das Objekt mit anderen Objekten zu vergleichen. Schauen wir uns das Beispiel in Listing 1–8 an, das eine Menge aus drei Strings erzeugt, nachdem deren Hash-Werte geprüft wurden. Sie versuchen, eine Menge aus Listen herzustellen, was nicht funktioniert, da Listen nicht Hash-fähig sind.
hero = "Harry"
guide = "Dumbledore"
enemy = "Lord V."
print(hash(hero))
# 6175908009919104006
print(hash(guide))
# -5197671124693729851
## Können wir aus Strings eine Menge erzeugen?
characters = {hero, guide, enemy}
print(characters)
# {'Lord V.', 'Dumbledore', 'Harry'}
## Können wir aus Listen eine Menge erzeugen?
team_1 = [hero, guide]
team_2 = [enemy]
teams = {team_1, team_2}
# TypeError: unhashable type: 'list'
Listing 1–8Der Datentyp set ist nur für Hash-fähige Elemente geeignet.
Sie können eine Menge aus Strings erzeugen, weil Strings Hash-fähig sind. Eine Menge aus Listen dagegen ist nicht möglich, da Listen nicht Hash-fähig sind. Das liegt daran, dass der Hash-Wert vom Inhalt des Elements abhängt und Listen veränderlich sind; wenn Sie den Listen-Datentyp ändern, muss sich auch der Hash-Wert ändern. Da veränderliche Datentypen nicht Hash-fähig sind, können Sie sie nicht in Mengen verwenden.
Ungeordnet
Anders als Listen haben die Elemente in einer Menge keine feste Reihenfolge. In welcher Reihenfolge auch immer Sie etwas in eine Menge legen – Sie können nie sicher sein, in welcher Anordnung diese Elemente gespeichert werden. Es folgt ein Beispiel:
characters = {hero, guide, enemy}
print(characters)
# {'Lord V.', 'Dumbledore', 'Harry'}
Ich setze den Helden zuerst hinein, doch mein Interpreter gibt den Feind zuerst aus (der Python-Interpreter steht offensichtlich auf der dunklen Seite). Ihr Interpreter kann aber auch eine ganz andere Reihung ausgeben.
Eindeutig
Alle Elemente in der Menge müssen eindeutig sein. Formell ausgedrückt heißt dies, dass zwei Werte x, y in der Menge mit x!=y unterschiedliche Hash-Werte haben: hash(x)!=hash(y). Da die zwei Elemente x und y in der Menge jeweils verschieden sind, können Sie keine Armee aus Harry-Potter-Klonen herstellen, um Lord V. zu bekämpfen:
clone_army = {hero, hero, hero, hero, hero, enemy}
print(clone_army)
# {'Lord V.', 'Harry'}
Egal, wie oft Sie denselben Wert in dieselbe Menge packen, die Menge speichert nur eine Instanz dieses Werts. Das liegt daran, dass diese Helden denselben Hash-Wert besitzen und eine Menge höchstens ein Element pro Hash-Wert enthalten darf. Eine Erweiterung der normalen Set-Datenstruktur ist die Multiset-Datenstruktur, die mehrere Instanzen desselben Werts speichern kann. Allerdings wird sie in der Praxis selten verwendet. Im Gegensatz dazu kommen Mengen in fast jedem nicht trivialen Codeprojekt vor – etwa um eine Menge von Kunden mit einer Menge von Personen zu kreuzen, die einen Laden besucht haben, wodurch eine neue Menge an Kunden zurückgeliefert wird, die auch den Laden besucht haben.
Dictionaries
Das Dictionary ist eine nützliche Datenstruktur zum Speichern von (Schlüssel, Wert)-Paaren:
calories = {'apple' : 52, 'banana' : 89, 'choco' : 546}
Sie können Elemente lesen und schreiben, indem Sie den Schlüssel in den eckigen Klammern angeben:
print(calories['apple'] < calories['choco'])
# True
calories['cappu'] = 74
print(calories['banana'] < calories['cappu'])
# False
Die Funktionen keys() und values() erlauben den Zugriff auf alle Schlüssel und Werte des Dictionary:
print('apple' in calories.keys())
# True
print(52 in calories.values())
# True
Mit der items()-Methode greifen Sie auf die (Schlüssel, Wert)-Paare eines Dictionary zu:
for k, v in calories.items():
print(k) if v > 500 else None
# 'choco'
Auf diese Weise können Sie leicht über alle Schlüssel und alle Werte in einem Dictionary iterieren, ohne einzeln auf sie zugreifen zu müssen.
Zugehörigkeit
Verwenden Sie das Schlüsselwort in, um zu prüfen, ob die Menge, Liste oder das Dictionary ein bestimmtes Element enthält (siehe Listing 1–9).
print(42 in [2, 39, 42])# True
print("21" in {"2", "39", "42"})
# False
print("list" in {"list" : [1, 2, 3], "set" : {1,2,3}})
# True
Listing 1–9 Das Schlüsselwort in benutzen
Sie verwenden das Schlüsselwort in zum Testen, ob der Integer-Wert 42
zu einer Liste von Integer-Werten oder ob der String-Wert "21" zu einer Menge von Strings gehört. Wir sagen, dass x ein Mitglied von y ist, falls das Element x in der Sammlung y auftaucht.Das Überprüfen von Mengenzugehörigkeiten geht schneller als das Überprüfen von Listenzugehörigkeiten: Um zu prüfen, ob das Element x in Liste y auftaucht, müssen Sie die ganze Liste durchlaufen, bis Sie x gefunden oder alle Elemente geprüft haben. Mengen dagegen sind fast wie Dictionaries implementiert: Um zu prüfen, ob das Element x in Menge y auftaucht, führt Python