Wiederkehrenden Code kürzer schreiben
Syntaktischer Zucker ist eine knappe Schreibweise für Verhalten, das sich auch ausführlicher ausdrücken ließe. Sie kann wiederkehrenden Ballast entfernen. Kürzerer Code ist aber nur dann hilfreich, wenn sein Zweck weiterhin klar bleibt.
Python bietet mehrere kompakte Formen für häufige Muster. Sie machen ein Programm nicht automatisch schneller und sind nicht in jedem Detail austauschbar. Wähle die Form, in der deine Absicht am leichtesten zu verstehen ist.
Listenkomprehension
Eine Listenkomprehension erzeugt eine neue Liste aus einem Iterable. Sie kann Werte transformieren, filtern oder beides in einem Ausdruck verbinden.
Listenkomprehensionen haben mehrere Syntaxformen:
# Grundform
newlist = [expression for item in iterable]
# Mit Bedingung
newlist = [expression for item in iterable if condition]
# Mit if-else (bedingter Ausdruck muss vor for stehen)
newlist = [if_expr if condition else else_expr for item in iterable]In der dritten Form steht der bedingte Ausdruck vor for. In der zweiten Form folgt die filternde if-Bedingung dagegen auf die Schleifenklausel.
Listenkomprehensionen in der Praxis
Die folgenden Beispiele unterscheiden einen bedingten Ausdruck von einem Filter.
# Ausgangsdaten
x = [1, 2, 3, 4, 5, 6]
# Bedingter Ausdruck innerhalb einer Listenkomprehension
parity = ["ungerade" if i % 2 else "gerade" for i in x]
print(parity)
# Ausgabe: ['ungerade', 'gerade', 'ungerade', 'gerade', 'ungerade', 'gerade']
# Ein weiteres Beispiel mit Bedingung
numbers = [1, 2, 3, 4, 5, 6]
result = [i**2 for i in numbers if i%2 == 0]
print(result)
# Ausgabe: [4, 16, 36]Verschachtelte Listenkomprehension
Python unterstützt auch verschachtelte Listenkomprehensionen, um mehrdimensionale Datenstrukturen zu verarbeiten:
# Matrixdaten
x = [[1, 2], [3, 4], [5, 6]]
# Verschachtelte Listenkomprehension
y = [col for row in x for col in row]
print(y)
# Ausgabe: [1, 2, 3, 4, 5, 6]
# Vergleich mit der Standardsyntax
y_standard = []
for row in x:
for col in row:
y_standard.append(col)
print(y_standard)
# Gleiche Ausgabe: [1, 2, 3, 4, 5, 6]Listenkomprehensionen können eine einfache Transformation oder einen Filter kompakt ausdrücken. Sie sind häufig effizient, doch Lesbarkeit ist wichtiger als eine geringe Zeilenzahl. Sobald der Ausdruck schwer verständlich wird, ist eine gewöhnliche Schleife die bessere Wahl. Die Schreibweise erinnert an die mathematische Mengennotation. Eine Python-Liste bewahrt jedoch Reihenfolge und Duplikate, eine mathematische Menge nicht.
Beispielsweise kann [i**2 for i in range(4)] die Liste [0, 1, 4, 9] erzeugen. Diese Quadratliste steht mit der mathematischen Notation in Beziehung.
Lambdafunktionen
Ein Lambda-Ausdruck erzeugt ein Funktionsobjekt ohne def-Anweisung. Er eignet sich besonders für eine kleine Funktion, die direkt als Argument übergeben wird.
Der Lambda-Körper besteht aus genau einem Ausdruck, dessen Wert zurückgegeben wird. Er darf eine Funktion wie print() aufrufen, aber keine Anweisungsformen wie return, eine gewöhnliche Zuweisung, for oder while enthalten. Ein Lambda kann an eine Variable gebunden werden. Für wiederverwendetes Verhalten ist eine benannte Funktion mit def meist klarer.
Lambda verwenden
Ein Lambda schreibt eine kleine Funktion in einem Ausdruck. Das Beispiel zeigt die Syntax und weist eine Funktion einem Namen zu.
# Grundlegende Lambda-Syntax
lambda parameters : expression
# Einfaches Lambda-Beispiel
square = lambda x: x**2
print(square(5)) # Ausgabe: 25
# Lambda mit mehreren Parametern
add = lambda x, y: x + y
print(add(3, 4)) # Ausgabe: 7
# Vergleich mit der regulären Funktion
def square_normal(x):
return x**2
def add_normal(x, y):
return x + yLambda mit integrierten Funktionen
Kurze Lambdas eignen sich als Callbacks, besonders als Sortierschlüssel über key für sorted(). Auch map() und filter() akzeptieren sie, wobei eine entsprechende Komprehension manchmal leichter lesbar ist:
# Mit map()
numbers = [1, 2, 3, 4, 5]
squared = list(map(lambda x: x**2, numbers))
print(squared) # Ausgabe: [1, 4, 9, 16, 25]
# Mit filter()
even_numbers = list(filter(lambda x: x%2 == 0, numbers))
print(even_numbers) # Ausgabe: [2, 4]
# Mit sorted()
students = [('Alice', 85), ('Bob', 90), ('Charlie', 78)]
sorted_by_grade = sorted(students, key=lambda student: student[1])
print(sorted_by_grade) # Ausgabe: [('Charlie', 78), ('Alice', 85), ('Bob', 90)]Andere syntaktische Zuckerfunktionen
Python besitzt weitere kompakte Schreibweisen für häufige Operationen. Sie können die Lesbarkeit verbessern, garantieren aber keine höhere Laufzeitgeschwindigkeit. Prüfe vor dem Ersetzen einer ausführlichen Form, ob das Verhalten übereinstimmt, besonders bei veränderlichen Objekten.
Zuweisungsoperatoren
Python bietet prägnantere Zuweisungsoperatoren für allgemeine Operationen:
# Verkürzte Zuweisung
a = 10
a += 1 # das gleiche wie: a = a + 1
print(a) # Ausgabe: 11
a -= 2 # Dasselbe wie: a = a - 2
print(a) # Ausgabe: 9
a *= 3 # das Gleiche wie: a = a * 3
print(a) # Ausgabe: 27
a /= 3 # das Gleiche wie: a = a / 3
print(a) # Ausgabe: 9.0Bei unveränderlichen Zahlen liefern diese Beispiele dieselben Werte wie die ausgeschriebenen Formen. Bei veränderlichen oder benutzerdefinierten Objekten kann += eine direkte Änderung ausführen. Es verhält sich deshalb nicht immer genauso wie eine neue Bindung mit a = a + value.
Negative Indizierung
Python erlaubt die Verwendung negativer Indizes, um von hinten auf Elemente zuzugreifen:
# Negative Indizierung
data = [10, 20, 30, 40, 50]
# Auf das letzte Element zugreifen
print(data[-1]) # Ausgabe: 50
# dasselbe wie: data[len(data) - 1]
print(data[-2]) # Ausgabe: 40
print(data[-3]) # Ausgabe: 30
# Slicing mit negativem Index
print(data[-3:]) # Ausgabe: [30, 40, 50]
print(data[:-2]) # Ausgabe: [10, 20, 30]Mehrfachzuweisung
Python ermöglicht die Zuweisung mehrerer Variablen in einer einzigen Zeile:
# Mehrfachzuweisung
x, y, z = 1, 2, 3
print(f"x={x}, y={y}, z={z}") # Ausgabe: x=1, y=2, z=3
# Liste entpacken
coordinates = [10, 20]
x, y = coordinates
print(f"x={x}, y={y}") # Ausgabe: x=10, y=20
# Variablen tauschen
a, b = 5, 10
print(f"Vorher: a={a}, b={b}")
a, b = b, a # Tauschen ohne temporäre Variable
print(f"Nachher: a={a}, b={b}") # Ausgabe: Nachher: a=10, b=5Syntaxvergleich
| Konzept | Standard-Syntax | Syntaktischer Zucker |
|---|---|---|
| Liste von Quadratzahlen erstellen | result = [], dann Schleife mit append() | result = [i**2 for i in range(5)] |
| Einfache Funktion | def double(x): return x * 2 | double = lambda x: x * 2 |
| Zuweisung | a = a + 5 | a += 5 |
| Auf das letzte Element zugreifen | data[len(data) - 1] | data[-1] |
Verwende die kompakte Form nur, wenn die Operation ohne verborgenen Kontrollfluss oder verborgene Nebenwirkungen erkennbar ist. Andernfalls ist die ausführliche Form geeigneter.