Zum Inhalt springen
Python Anfänger 2 min

Sets und Tuples in Python

Lerne alles über Tuples und Sets in Python: unveränderliche Sequenzen, einzigartige Sammlungen, Mengenoperationen und wann du welche Datenstruktur verwendest.

Aktualisiert:

Sets und Tuples in Python

Neben Listen und Dictionaries gibt es in Python zwei weitere wichtige Datenstrukturen: Tuples (unveränderliche Listen) und Sets (Mengen mit einzigartigen Elementen). In diesem Tutorial lernst du, wann und wie du diese Strukturen effektiv einsetzt.

Tuples: Unveränderliche Listen

Ein Tuple ist wie eine Liste, aber unveränderbar (immutable). Einmal erstellt, können keine Elemente hinzugefügt, entfernt oder geändert werden.

Tuple erstellen

# Mit runden Klammern
koordinaten = (10, 20)
farben = ("rot", "grün", "blau")
gemischt = (42, "Hallo", True, 3.14)

# Ohne Klammern (auch gültig, aber weniger lesbar)
punkt = 5, 10
print(punkt)       # (5, 10)
print(type(punkt)) # <class 'tuple'>

# Mit dem tuple()-Konstruktor
aus_liste = tuple([1, 2, 3])
aus_string = tuple("Python")
print(aus_string)  # ('P', 'y', 't', 'h', 'o', 'n')

# Leeres Tuple
leer = ()
auch_leer = tuple()

# ACHTUNG: Tuple mit einem Element braucht ein Komma!
kein_tuple = (42)     # Das ist nur eine Zahl!
print(type(kein_tuple))  # <class 'int'>

ein_element = (42,)   # DAS ist ein Tuple
print(type(ein_element)) # <class 'tuple'>

# Oder ohne Klammern:
auch_tuple = 42,
print(type(auch_tuple))  # <class 'tuple'>

Auf Tuple-Elemente zugreifen

fruechte = ("Apfel", "Banane", "Kirsche", "Dattel")

# Indizierung (wie bei Listen)
print(fruechte[0])    # Apfel
print(fruechte[-1])   # Dattel
print(fruechte[1:3])  # ('Banane', 'Kirsche')

# Tuple-Methoden
print(fruechte.count("Banane"))  # 1
print(fruechte.index("Kirsche")) # 2
print(len(fruechte))             # 4

# Prüfen, ob Element vorhanden
print("Apfel" in fruechte)  # True

# ABER: Verändern ist NICHT möglich!
# fruechte[0] = "Mango"  # TypeError: 'tuple' object does not support item assignment
# fruechte.append("Mango")  # AttributeError: 'tuple' object has no attribute 'append'

Tuple Unpacking

Eine der nützlichsten Funktionen von Tuples ist das Unpacking (Entpacken):

# Einfaches Unpacking
koordinaten = (10, 20, 30)
x, y, z = koordinaten
print(x)  # 10
print(y)  # 20
print(z)  # 30

# Variablen tauschen (ohne temporäre Variable!)
a = 5
b = 10
a, b = b, a
print(a, b)  # 10 5

# Funktion mit mehreren Rückgabewerten
def min_max(zahlen):
    return min(zahlen), max(zahlen)

kleinste, groesste = min_max([3, 1, 7, 2, 9])
print(f"Min: {kleinste}, Max: {groesste}")  # Min: 1, Max: 9

# Extended Unpacking mit *
erste, *rest = (1, 2, 3, 4, 5)
print(erste)  # 1
print(rest)   # [2, 3, 4, 5] (als Liste!)

erste, *mitte, letzte = (1, 2, 3, 4, 5)
print(erste)  # 1
print(mitte)  # [2, 3, 4]
print(letzte) # 5

# Unpacking in Schleifen
punkte = [(1, 2), (3, 4), (5, 6)]
for x, y in punkte:
    print(f"x={x}, y={y}")

# Unpacking mit enumerate
namen = ["Anna", "Ben", "Clara"]
for index, name in enumerate(namen):
    print(f"{index}: {name}")

Wann Tuples statt Listen?

Verwende Tuples, wenn:

# 1. Daten sich nicht ändern sollen (Schutz vor Veränderung)
WOCHENTAGE = ("Montag", "Dienstag", "Mittwoch", "Donnerstag",
              "Freitag", "Samstag", "Sonntag")

# 2. Als Dictionary-Schlüssel (Listen können das nicht!)
standorte = {
    (52.52, 13.405): "Berlin",
    (48.137, 11.576): "München",
    (50.938, 6.957): "Köln"
}
print(standorte[(52.52, 13.405)])  # Berlin

# 3. Für Funktionsrückgaben mit mehreren Werten
def teile(a, b):
    quotient = a // b
    rest = a % b
    return quotient, rest  # Gibt ein Tuple zurück

ergebnis = teile(17, 5)
print(ergebnis)  # (3, 2)
q, r = teile(17, 5)  # Direkt entpacken

# 4. Tuples sind schneller und verbrauchen weniger Speicher
import sys
liste = [1, 2, 3, 4, 5]
tupel = (1, 2, 3, 4, 5)
print(sys.getsizeof(liste))  # z.B. 120 Bytes
print(sys.getsizeof(tupel))  # z.B. 80 Bytes

Named Tuples

Für bessere Lesbarkeit kannst du Named Tuples verwenden:

from collections import namedtuple

# Named Tuple definieren
Punkt = namedtuple("Punkt", ["x", "y"])
Farbe = namedtuple("Farbe", "rot gruen blau")

# Instanzen erstellen
p1 = Punkt(10, 20)
p2 = Punkt(x=30, y=40)
rot = Farbe(255, 0, 0)

# Zugriff über Namen (lesbar!) oder Index
print(p1.x)     # 10
print(p1.y)     # 20
print(p1[0])    # 10 (auch per Index)
print(rot.rot)  # 255

# Named Tuples sind immer noch Tuples
print(isinstance(p1, tuple))  # True

# Nützliche Methoden
print(p1._asdict())   # {'x': 10, 'y': 20}
p3 = p1._replace(x=50)
print(p3)  # Punkt(x=50, y=20) -- neues Tuple!

# Praxis-Beispiel: Studentendaten
Student = namedtuple("Student", ["name", "alter", "fach", "note"])

studenten = [
    Student("Anna", 22, "Informatik", 1.3),
    Student("Ben", 24, "Mathematik", 2.0),
    Student("Clara", 21, "Physik", 1.7)
]

for s in studenten:
    print(f"{s.name} ({s.alter}): {s.fach}, Note {s.note}")

# Besten Studenten finden
beste = min(studenten, key=lambda s: s.note)
print(f"\nBeste Note: {beste.name} mit {beste.note}")

Sets: Einzigartige Elemente

Ein Set ist eine ungeordnete Sammlung von einzigartigen Elementen. Duplikate werden automatisch entfernt.

Set erstellen

# Mit geschweiften Klammern
farben = {"rot", "grün", "blau"}
print(farben)  # {'rot', 'blau', 'grün'} (Reihenfolge kann variieren!)

# Duplikate werden automatisch entfernt
zahlen = {1, 2, 3, 2, 1, 4, 3}
print(zahlen)  # {1, 2, 3, 4}

# Mit dem set()-Konstruktor
aus_liste = set([1, 2, 3, 2, 1])
print(aus_liste)  # {1, 2, 3}

aus_string = set("Mississippi")
print(aus_string)  # {'M', 'i', 's', 'p'}

# ACHTUNG: Leeres Set NUR mit set()!
leeres_set = set()      # Leeres Set
leeres_dict = {}         # Leeres DICTIONARY, KEIN Set!
print(type(leeres_set))  # <class 'set'>
print(type(leeres_dict)) # <class 'dict'>

Set-Operationen (Mengenoperationen)

Sets unterstützen mathematische Mengenoperationen:

python_devs = {"Anna", "Ben", "Clara", "David"}
java_devs = {"Clara", "David", "Eva", "Frank"}

# Vereinigung (Union) -- alle aus beiden Sets
alle = python_devs | java_devs
# ODER: alle = python_devs.union(java_devs)
print(alle)
# {'Anna', 'Ben', 'Clara', 'David', 'Eva', 'Frank'}

# Schnittmenge (Intersection) -- nur gemeinsame
gemeinsam = python_devs & java_devs
# ODER: gemeinsam = python_devs.intersection(java_devs)
print(gemeinsam)  # {'Clara', 'David'}

# Differenz -- nur in der ersten, nicht in der zweiten
nur_python = python_devs - java_devs
# ODER: nur_python = python_devs.difference(java_devs)
print(nur_python)  # {'Anna', 'Ben'}

nur_java = java_devs - python_devs
print(nur_java)    # {'Eva', 'Frank'}

# Symmetrische Differenz -- in einer, aber nicht in beiden
entweder_oder = python_devs ^ java_devs
# ODER: entweder_oder = python_devs.symmetric_difference(java_devs)
print(entweder_oder)  # {'Anna', 'Ben', 'Eva', 'Frank'}

# Teilmenge und Obermenge prüfen
a = {1, 2, 3}
b = {1, 2, 3, 4, 5}

print(a.issubset(b))    # True (a ist Teilmenge von b)
print(a <= b)            # True (gleicher Operator)
print(b.issuperset(a))  # True (b ist Obermenge von a)
print(b >= a)            # True

# Disjunkt prüfen (keine gemeinsamen Elemente)
c = {6, 7, 8}
print(a.isdisjoint(c))  # True
print(a.isdisjoint(b))  # False

Elemente hinzufügen und entfernen

mein_set = {1, 2, 3}

# Ein Element hinzufügen
mein_set.add(4)
print(mein_set)  # {1, 2, 3, 4}

# Bereits vorhandenes Element hinzufügen (kein Fehler!)
mein_set.add(3)
print(mein_set)  # {1, 2, 3, 4} -- keine Änderung

# Mehrere Elemente hinzufügen
mein_set.update([5, 6, 7])
print(mein_set)  # {1, 2, 3, 4, 5, 6, 7}

# Element entfernen (wirft KeyError, wenn nicht vorhanden)
mein_set.remove(3)
print(mein_set)  # {1, 2, 4, 5, 6, 7}
# mein_set.remove(99)  # KeyError!

# Element sicher entfernen (kein Fehler, wenn nicht vorhanden)
mein_set.discard(99)   # Kein Fehler
mein_set.discard(2)
print(mein_set)  # {1, 4, 5, 6, 7}

# Beliebiges Element entfernen und zurückgeben
element = mein_set.pop()
print(f"Entfernt: {element}")

# Set leeren
mein_set.clear()
print(mein_set)  # set()

frozenset

Ein frozenset ist ein unveränderliches Set:

# frozenset erstellen
unveraenderlich = frozenset([1, 2, 3, 4])

# Lesen funktioniert wie bei normalen Sets
print(3 in unveraenderlich)  # True
print(len(unveraenderlich))  # 4

# Mengenoperationen funktionieren
a = frozenset([1, 2, 3])
b = frozenset([3, 4, 5])
print(a | b)  # frozenset({1, 2, 3, 4, 5})
print(a & b)  # frozenset({3})

# ABER: Verändern ist nicht möglich!
# unveraenderlich.add(5)     # AttributeError
# unveraenderlich.remove(1)  # AttributeError

# Vorteil: Kann als Dictionary-Schlüssel oder in Sets verwendet werden
mein_dict = {frozenset([1, 2]): "Paar"}
mein_set = {frozenset([1, 2]), frozenset([3, 4])}

Praxis: Duplikate entfernen

# Einfachster Weg, Duplikate zu entfernen
zahlen = [1, 3, 2, 3, 1, 4, 2, 5, 3]
eindeutig = list(set(zahlen))
print(eindeutig)  # [1, 2, 3, 4, 5] (Reihenfolge nicht garantiert!)

# Duplikate entfernen UND Reihenfolge beibehalten
def ohne_duplikate(liste):
    gesehen = set()
    ergebnis = []
    for element in liste:
        if element not in gesehen:
            gesehen.add(element)
            ergebnis.append(element)
    return ergebnis

print(ohne_duplikate([1, 3, 2, 3, 1, 4, 2]))
# [1, 3, 2, 4] -- Reihenfolge beibehalten!

# Gemeinsame und unterschiedliche Elemente finden
liste_a = [1, 2, 3, 4, 5]
liste_b = [4, 5, 6, 7, 8]

gemeinsam = set(liste_a) & set(liste_b)
print(f"Gemeinsam: {gemeinsam}")       # {4, 5}

nur_a = set(liste_a) - set(liste_b)
print(f"Nur in A: {nur_a}")            # {1, 2, 3}

nur_b = set(liste_b) - set(liste_a)
print(f"Nur in B: {nur_b}")            # {6, 7, 8}

alle = set(liste_a) | set(liste_b)
print(f"Alle zusammen: {alle}")        # {1, 2, 3, 4, 5, 6, 7, 8}

Praxis: Mengenvergleiche

# Kursanmeldungen vergleichen
kurs_python = {"Anna", "Ben", "Clara", "David", "Eva"}
kurs_datenbanken = {"Clara", "Eva", "Frank", "Gina"}
kurs_webdev = {"Anna", "David", "Frank", "Hannah"}

# Wer besucht Python UND Datenbanken?
print("Python + DB:", kurs_python & kurs_datenbanken)
# {'Clara', 'Eva'}

# Wer besucht mindestens einen Kurs?
alle_studenten = kurs_python | kurs_datenbanken | kurs_webdev
print(f"Alle Studenten: {len(alle_studenten)}")
print(alle_studenten)

# Wer besucht NUR Python?
nur_python = kurs_python - kurs_datenbanken - kurs_webdev
print(f"Nur Python: {nur_python}")  # {'Ben'}

# Wer besucht alle drei Kurse?
alle_drei = kurs_python & kurs_datenbanken & kurs_webdev
print(f"Alle drei Kurse: {alle_drei}")  # set() -- niemand

# Wer besucht genau zwei Kurse?
# (in mindestens zwei, aber nicht in allen drei)
in_zwei = ((kurs_python & kurs_datenbanken) |
           (kurs_python & kurs_webdev) |
           (kurs_datenbanken & kurs_webdev)) - alle_drei
print(f"Genau in zwei Kursen: {in_zwei}")

Vergleichstabelle: List vs Tuple vs Set vs Dict

EigenschaftListTupleSetDict
Syntax[1, 2, 3](1, 2, 3){1, 2, 3}{"a": 1}
VeränderbarJaNeinJaJa
GeordnetJaJaNeinJa (ab 3.7)
DuplikateJaJaNeinKeys: Nein
IndizierungJa [0]Ja [0]NeinPer Key ["a"]
SlicingJaJaNeinNein
Suche (in)O(n) langsamO(n) langsamO(1) schnellO(1) schnell
Dict-SchlüsselNeinJaNein*
VerwendungSammlungenKonstantenEinzigartige WerteZuordnungen

*frozensets können als Dictionary-Schlüssel verwendet werden.

# Zusammenfassung der Erstellung
meine_liste   = [1, 2, 3]          # veränderbar, geordnet, Duplikate OK
mein_tuple     = (1, 2, 3)          # unveränderbar, geordnet, Duplikate OK
mein_set       = {1, 2, 3}          # veränderbar, ungeordnet, keine Duplikate
mein_dict      = {"a": 1, "b": 2}   # veränderbar, geordnet, Keys einzigartig

# Umwandlung zwischen Typen
zahlen = [1, 2, 3, 2, 1]
print(tuple(zahlen))   # (1, 2, 3, 2, 1)
print(set(zahlen))     # {1, 2, 3}
print(list(set(zahlen)))  # [1, 2, 3]

Übungen

Übung 1: Tuple-Operationen

Erstelle ein Programm, das Koordinaten als Tuples verwaltet und die Distanz zwischen zwei Punkten berechnet.

import math

def distanz(punkt1, punkt2):
    """Berechne die euklidische Distanz zwischen zwei Punkten."""
    # Deine Lösung hier
    pass

# Test
p1 = (0, 0)
p2 = (3, 4)
print(distanz(p1, p2))  # 5.0

p3 = (1, 1)
p4 = (4, 5)
print(distanz(p3, p4))  # 5.0

Übung 2: Set-Operationen mit Wortschatz

Zwei Schüler lernen Vokabeln. Finde heraus, welche Wörter beide kennen, welche nur einer kennt, und welche sie zusammen kennen.

schueler_a = {"Hund", "Katze", "Haus", "Auto", "Baum", "Blume"}
schueler_b = {"Katze", "Blume", "Sonne", "Mond", "Baum", "Stern"}

# Deine Lösung hier:
# 1. Welche Wörter kennen beide?
# 2. Welche kennt nur Schüler A?
# 3. Welche kennt nur Schüler B?
# 4. Wie viele verschiedene Wörter kennen sie zusammen?

Übung 3: Named Tuple für Produkte

Erstelle ein Warenwirtschaftssystem mit Named Tuples.

from collections import namedtuple

# Definiere einen Named Tuple "Produkt" mit: name, preis, menge, kategorie
# Erstelle eine Liste von mindestens 5 Produkten
# Berechne:
#   - Den Gesamtwert aller Produkte (preis * menge)
#   - Das teuerste Produkt
#   - Alle Produkte einer bestimmten Kategorie

Übung 4: Anagramm-Prüfer

Schreibe eine Funktion, die prüft, ob zwei Wörter Anagramme sind (gleiche Buchstaben, andere Reihenfolge).

def ist_anagramm(wort1, wort2):
    # Deine Lösung hier (verwende Sets und/oder Sortierung)
    pass

# Tests
print(ist_anagramm("listen", "silent"))  # True
print(ist_anagramm("hallo", "welt"))     # False
print(ist_anagramm("Erde", "Rede"))      # True

Pro-Tipp: Verwende Set Comprehensions fuer kompakte Set-Erstellung:

# Set Comprehension
quadrate = {x**2 for x in range(10)}
print(quadrate)  # {0, 1, 4, 9, 16, 25, 36, 49, 64, 81}

# Einzigartige Wortlängen aus einem Text
text = "der kleine Hund und die große Katze"
laengen = {len(wort) for wort in text.split()}
print(laengen)  # {3, 5, 6}

# Alle einzigartigen Anfangsbuchstaben
anfang = {wort[0].upper() for wort in text.split()}
print(anfang)  # {'D', 'K', 'H', 'U', 'G'}

Sets sind ideal fuer Mitgliedschaftstestsx in mein_set ist viel schneller als x in meine_liste, besonders bei grossen Datenmengen!

Zurück zum Python Kurs