Python & AI Tutorials Logo
Python Programmierung

23. First-Class-Funktionen und funktionale Techniken

In den vorherigen Kapiteln haben wir gelernt, wie man Funktionen definiert und aufruft, mit Parametern und Argumenten arbeitet und den Geltungsbereich von Variablen (variable scope) versteht. Jetzt werden wir eine leistungsstarke Eigenschaft erkunden, die Python auszeichnet: Funktionen sind First-Class-Objekte (first-class objects). Das bedeutet, Funktionen können wie jeder andere Wert behandelt werden—sie können in Variablen gespeichert, als Argumente an andere Funktionen übergeben und von Funktionen zurückgegeben werden.

Diese Fähigkeit eröffnet elegante Programmiertechniken, die Code flexibler, wiederverwendbarer und ausdrucksstärker machen. Wir werden untersuchen, wie Sie First-Class-Funktionen (first-class functions) anhand praktischer Beispiele nutzen, Closures (closures), also Funktionen, die sich ihre Umgebung „merken“, verstehen, Lambda-Ausdrücke (lambda expressions) für prägnante Funktionsdefinitionen verwenden und eingebaute Funktionen wie map() und filter() anwenden, um effizient mit Sammlungen zu arbeiten.

23.1) Funktionen als First-Class-Objekte

23.1.1) Was „First-Class“ bedeutet

In Python sind Funktionen First-Class-Objekte, was bedeutet, dass sie:

  • Variablen zugewiesen werden können
  • In Datenstrukturen (Listen, Dictionaries usw.) gespeichert werden können
  • Als Argumente an andere Funktionen übergeben werden können
  • Als Werte von anderen Funktionen zurückgegeben werden können

Das unterscheidet sich von einigen Programmiersprachen, in denen Funktionen einen Sonderstatus haben und nicht wie normale Werte manipuliert werden können. In Python ist eine Funktion einfach ein weiterer Objekttyp, ähnlich wie Integer, Strings oder Listen.

Sehen wir uns das in Aktion an:

python
# Eine einfache Funktion definieren
def greet(name):
    return f"Hello, {name}!"
 
# Die Funktion einer Variable zuweisen
say_hello = greet
 
# Die Funktion über die neue Variable aufrufen
message = say_hello("Alice")
print(message)  # Output: Hello, Alice!
 
# Prüfen, dass beide Namen auf dieselbe Funktion verweisen
print(greet)      # Output: <function greet at 0x...>
print(say_hello)  # Output: <function greet at 0x...>
print(greet is say_hello)  # Output: True

Beachten Sie, dass wir bei say_hello = greet die Funktion nicht aufrufen (keine Klammern). Wir erstellen einen neuen Namen, der auf dasselbe Funktionsobjekt verweist. Sowohl greet als auch say_hello zeigen jetzt auf dieselbe Funktion, was wir mit dem Operator is überprüfen können.

23.1.2) Funktionen in Datenstrukturen speichern

Da Funktionen Objekte sind, können wir sie in Listen, Dictionaries oder jeder anderen Sammlung (Collection) speichern:

python
# Rechner mit Operationen, die in einem Dictionary gespeichert sind
def add(x, y):
    return x + y
 
def subtract(x, y):
    return x - y
 
def multiply(x, y):
    return x * y
 
def divide(x, y):
    return x / y
 
# Funktionen in einem Dictionary speichern
operations = {
    '+': add,
    '-': subtract,
    '*': multiply,
    '/': divide
}
 
# Das Dictionary verwenden, um Berechnungen durchzuführen
num1 = 10
num2 = 5
operator = '*'
 
result = operations[operator](num1, num2)
print(f"{num1} {operator} {num2} = {result}")  # Output: 10 * 5 = 50

Dieses Muster ist äußerst nützlich, um flexible Systeme zu bauen. Statt lange Ketten von if-elif-Anweisungen zu schreiben, um auszuwählen, welche Funktion aufgerufen werden soll, können wir die passende Funktion in einem Dictionary nachschlagen und direkt aufrufen.

23.2) Funktionen als Argumente übergeben

23.2.1) Das Grundkonzept

Eine der mächtigsten Anwendungen von First-Class Functions ist, sie als Argumente an andere Funktionen zu übergeben. Dadurch können wir flexiblen, wiederverwendbaren Code schreiben, der mit unterschiedlichen Verhaltensweisen arbeiten kann.

Hier ist ein einfaches Beispiel:

python
# Funktion, die eine andere Funktion auf einen Wert anwendet
def apply_operation(value, operation):
    """Wendet die als Parameter übergebene Funktion auf den Wert an."""
    return operation(value)
 
# Verschiedene Operationen
def double(x):
    return x * 2
 
def square(x):
    return x * x
 
def negate(x):
    return -x
 
# Dieselbe apply_operation-Funktion mit verschiedenen Operationen verwenden
number = 5
print(apply_operation(number, double))   # Output: 10
print(apply_operation(number, square))   # Output: 25
print(apply_operation(number, negate))   # Output: -5

Die Funktion apply_operation weiß nicht und es ist ihr egal, welche konkrete Operation sie ausführt. Sie ruft einfach die Funktion auf, die ihr übergeben wird. Diese Trennung der Verantwortlichkeiten macht Code modularer und leichter erweiterbar.

23.2.2) Sammlungen mit benutzerdefinierten Funktionen verarbeiten

Ein häufiges Muster ist, jedes Element in einer Sammlung mit einer als Argument übergebenen Funktion zu verarbeiten:

python
# Jedes Element in einer Liste mit einer gegebenen Funktion verarbeiten
def process_list(items, processor):
    """Wendet die processor-Funktion auf jedes Element in der Liste an."""
    results = []
    for item in items:
        results.append(processor(item))
    return results
 
# Verschiedene Verarbeitungsfunktionen
def uppercase(text):
    return text.upper()
 
def add_exclamation(text):
    return text + "!"
 
def get_length(text):
    return len(text)
 
# Dieselbe Liste auf verschiedene Arten verarbeiten
words = ["hello", "world", "python"]
 
print(process_list(words, uppercase))        # Output: ['HELLO', 'WORLD', 'PYTHON']
print(process_list(words, add_exclamation))  # Output: ['hello!', 'world!', 'python!']
print(process_list(words, get_length))       # Output: [5, 5, 6]

Dieses Muster ist so nützlich, dass Python eingebaute Funktionen wie map() und filter() bereitstellt, die auf diese Weise arbeiten (wir werden diese in Abschnitt 23.6 erkunden).

23.2.3) Sortieren durch Bereitstellen einer Key-Funktion (Kurze Einführung)

Pythons Funktion sorted() akzeptiert einen Parameter key—eine Funktion, die bestimmt, wie Elemente verglichen werden:

python
# Schüler nach verschiedenen Kriterien sortieren
students = [
    {"name": "Alice", "grade": 85, "age": 20},
    {"name": "Bob", "grade": 92, "age": 19},
    {"name": "Charlie", "grade": 78, "age": 21},
    {"name": "Diana", "grade": 95, "age": 20}
]
 
# Funktion, um die Note zu extrahieren
def get_grade(student):
    return student["grade"]
 
# Funktion, um den Namen zu extrahieren
def get_name(student):
    return student["name"]
 
# Nach Note sortieren (aufsteigend)
by_grade = sorted(students, key=get_grade)
print("Sorted by grade:")
for student in by_grade:
    print(f"  {student['name']}: {student['grade']}")
# Output:
#   Charlie: 78
#   Alice: 85
#   Bob: 92
#   Diana: 95
 
# Nach Name sortieren (alphabetisch)
by_name = sorted(students, key=get_name)
print("\nSorted by name:")
for student in by_name:
    print(f"  {student['name']}: {student['grade']}")
# Output:
#   Alice: 85
#   Bob: 92
#   Charlie: 78
#   Diana: 95

Die key-Funktion wird für jedes Element genau einmal aufgerufen, und ihr Rückgabewert wird für den Vergleich verwendet. Das ist viel flexibler, als eigene Sortierlogik schreiben zu müssen.

Dieses Muster, Funktionen zu übergeben, um Verhalten anzupassen, ist in Python äußerst verbreitet. Wir werden fortgeschrittenere Sortiertechniken in Kapitel 38 erkunden.

23.3) Funktionen aus Funktionen zurückgeben

23.3.1) Funktionen, die Funktionen erzeugen

So wie wir Funktionen als Argumente übergeben können, können wir auch Funktionen aus anderen Funktionen zurückgeben. Dadurch können wir dynamisch spezialisierte Funktionen erzeugen:

python
# Funktion, die eine neue Funktion erzeugt und zurückgibt
def create_multiplier(factor):
    """Erstellt eine Funktion, die mit dem gegebenen factor multipliziert."""
    def multiplier(x):
        return x * factor
    return multiplier
 
# Spezialisierte Multiplikator-Funktionen erstellen
double = create_multiplier(2)
triple = create_multiplier(3)
times_ten = create_multiplier(10)
 
# Die erzeugten Funktionen verwenden
print(double(5))      # Output: 10
print(triple(5))      # Output: 15
print(times_ten(5))   # Output: 50

Was passiert hier? Die Funktion create_multiplier definiert eine innere Funktion namens multiplier und gibt sie zurück. Jedes Mal, wenn wir create_multiplier mit einem anderen Faktor aufrufen, bekommen wir eine neue Funktion zurück, die sich diesen spezifischen Faktor „merkt“. Das ist unser erster Einblick in Closures, die wir im nächsten Abschnitt ausführlich betrachten werden.

23.3.2) Benutzerdefinierte Validatoren erstellen

Das Zurückgeben von Funktionen ist besonders nützlich, um benutzerdefinierte Validierungs- oder Verarbeitungsfunktionen zu erzeugen:

python
# Bereichsvalidatoren dynamisch erstellen
def create_range_validator(min_value, max_value):
    """Erstellt eine Funktion, die prüft, ob eine Zahl im Bereich liegt."""
    def validator(number):
        return min_value <= number <= max_value
    return validator
 
# Spezifische Validatoren erstellen
is_valid_age = create_range_validator(0, 120)
is_valid_percentage = create_range_validator(0, 100)
is_room_temperature = create_range_validator(15, 30)
 
# Die Validatoren verwenden
age = 25
print(f"Is {age} a valid age? {is_valid_age(age)}")  # Output: True
 
temp = 22
print(f"Is {temp}°C room temperature? {is_room_temperature(temp)}")  # Output: True
 
score = 150
print(f"Is {score} a valid percentage? {is_valid_percentage(score)}")  # Output: False

23.4) Closures verstehen: Funktionen, die sich erinnern

23.4.1) Was ist eine Closure?

Eine Closure ist eine Funktion, die Variablen aus dem Scope, in dem sie erstellt wurde, „merkt“, selbst nachdem dieser Scope fertig ausgeführt wurde. In den Beispielen aus Abschnitt 23.3 haben wir Closures bereits verwendet, ohne sie explizit so zu nennen.

Sehen wir uns an, wie Closures funktionieren:

python
def create_counter(start=0):
    """Erstellt eine Zählerfunktion, die sich ihren count merkt."""
    count = start  # Diese Variable wird von der Closure „eingefangen“
    
    def counter():
        nonlocal count  # Auf die eingefangene Variable zugreifen
        count += 1
        return count
    
    return counter
 
# Zwei unabhängige Zähler erstellen
counter1 = create_counter(0)
counter2 = create_counter(100)
 
# Jeder Zähler verwaltet seinen eigenen count
print(counter1())  # Output: 1
print(counter1())  # Output: 2
print(counter1())  # Output: 3
 
print(counter2())  # Output: 101
print(counter2())  # Output: 102
 
print(counter1())  # Output: 4 (counter1 is independent of counter2)

Die innere Funktion counter bildet eine Closure über die Variable count. Obwohl create_counter die Ausführung beendet hat, hat die zurückgegebene Funktion counter weiterhin Zugriff auf count. Jeder Aufruf von create_counter erzeugt eine neue, unabhängige Closure mit ihrer eigenen count-Variable.

23.4.2) Wie Closures Variablen einfangen

Wenn eine Funktion innerhalb einer anderen Funktion definiert wird, kann sie auf Variablen aus dem Scope der äußeren Funktion zugreifen. Diese Variablen werden „eingefangen“ und bleiben auch dann zugänglich, nachdem die äußere Funktion zurückkehrt:

Wenn Python die innere Funktion erstellt, speichert es nicht nur den Funktionscode—es speichert auch Referenzen auf alle Variablen aus der äußeren Funktion, die die innere Funktion verwendet. Dieser Prozess wird als „capturing“ von Variablen bezeichnet.

python
def create_greeter(greeting):
    """Erstellt eine Begrüßungsfunktion mit einer benutzerdefinierten greeting."""
    def greet(name):
        return f"{greeting}, {name}!"
    return greet
 
# Verschiedene Greeter erstellen
say_hello = create_greeter("Hello")
say_hi = create_greeter("Hi")
say_bonjour = create_greeter("Bonjour")
 
# Jeder Greeter merkt sich seine spezifische Begrüßung
print(say_hello("Alice"))    # Output: Hello, Alice!
print(say_hi("Bob"))         # Output: Hi, Bob!
print(say_bonjour("Claire")) # Output: Bonjour, Claire!

Der Parameter greeting wird von der Closure eingefangen. Jede Greeter-Funktion hat ihren eigenen eingefangenen greeting-Wert, den sie bei jedem Aufruf verwendet.

23.4.3) Praktischer Einsatz: Konfigurationsfunktionen

Closures eignen sich hervorragend, um Funktionen mit vorkonfiguriertem Verhalten zu erstellen:

python
# Preisrechner mit unterschiedlichen Steuersätzen erstellen
def create_price_calculator(tax_rate):
    """Erstellt einen Rechner, der einen bestimmten Steuersatz anwendet."""
    def calculate_total(price):
        tax = price * tax_rate
        return price + tax
    return calculate_total
 
# Rechner für verschiedene Regionen erstellen
us_calculator = create_price_calculator(0.07)    # 7% tax
uk_calculator = create_price_calculator(0.20)    # 20% VAT
japan_calculator = create_price_calculator(0.10) # 10% consumption tax
 
# Preise in verschiedenen Regionen berechnen
item_price = 100
 
print(f"US total: ${us_calculator(item_price):.2f}")      # Output: US total: $107.00
print(f"UK total: £{uk_calculator(item_price):.2f}")      # Output: UK total: £120.00
print(f"Japan total: ¥{japan_calculator(item_price):.2f}") # Output: Japan total: ¥110.00

23.4.4) Wann man Closures verwenden sollte

Closures sind besonders nützlich, wenn Sie:

  • Funktionen mit vorkonfiguriertem Verhalten erstellen müssen
  • Zustand zwischen Funktionsaufrufen halten möchten, ohne Klassen zu verwenden
  • Callback-Funktionen implementieren, die sich Kontext merken müssen
  • Function-Factories erstellen, die spezialisierte Funktionen produzieren

23.5) lambda für kurze anonyme Funktionen verwenden

23.5.1) Was sind Lambda-Ausdrücke?

Ein Lambda-Ausdruck erstellt eine kleine, anonyme Funktion—eine Funktion ohne Namen. Lambda-Ausdrücke sind nützlich, wenn Sie für kurze Zeit eine einfache Funktion benötigen und sie nicht formal mit def definieren möchten.

Die Syntax ist:

python
lambda parameters: expression

Das Lambda nimmt Parameter (wie eine normale Funktion) und gibt das Ergebnis der Auswertung des Ausdrucks zurück. Hier ist ein einfaches Beispiel:

python
# Normale Funktion
def add(x, y):
    return x + y
 
# Entsprechender Lambda-Ausdruck
add_lambda = lambda x, y: x + y
 
# Beide funktionieren auf die gleiche Weise
print(add(3, 5))        # Output: 8
print(add_lambda(3, 5)) # Output: 8

Lambda-Ausdrücke sind auf einen einzelnen Ausdruck beschränkt—sie können keine Anweisungen wie if, for oder mehrere Codezeilen enthalten. Diese Einschränkung hält sie einfach und fokussiert.

23.5.2) Lambda-Ausdrücke als Argumente

Lambda-Ausdrücke glänzen, wenn Sie eine einfache Funktion als Argument übergeben müssen und keine separate benannte Funktion definieren möchten:

python
# Schüler nach Note sortieren mit lambda
students = [
    {"name": "Alice", "grade": 85},
    {"name": "Bob", "grade": 92},
    {"name": "Charlie", "grade": 78},
    {"name": "Diana", "grade": 95}
]
 
# Anstatt eine separate Funktion zu definieren:
# def get_grade(student):
#     return student["grade"]
# sorted_students = sorted(students, key=get_grade)
 
# Wir können direkt ein Lambda verwenden:
sorted_students = sorted(students, key=lambda student: student["grade"])
 
print("Students sorted by grade:")
for student in sorted_students:
    print(f"  {student['name']}: {student['grade']}")
# Output:
#   Charlie: 78
#   Alice: 85
#   Bob: 92
#   Diana: 95

Das ist kürzer, wenn die Funktion einfach ist und nur einmal verwendet wird. Das Lambda lambda student: student["grade"] ist äquivalent zu einer Funktion, die einen Schüler entgegennimmt und seine Note zurückgibt.

23.5.3) Lambda mit mehreren Parametern

Lambda-Ausdrücke können mehrere Parameter annehmen, genau wie normale Funktionen:

python
# Rechner-Operationen mit lambda
operations = {
    'add': lambda x, y: x + y,
    'subtract': lambda x, y: x - y,
    'multiply': lambda x, y: x * y,
    'divide': lambda x, y: x / y if y != 0 else "Error"
}
 
# Die Lambda-Ausdrücke verwenden
print(operations['add'](10, 5))       # Output: 15
print(operations['multiply'](10, 5))  # Output: 50
print(operations['divide'](10, 0))    # Output: Error

Beachten Sie, wie wir einen bedingten Ausdruck (x / y if y != 0 else "Error") innerhalb eines Lambda verwenden können, aber keine if-Anweisung (die mehrere Zeilen erfordern würde).

23.5.4) Wann man Lambda vs. benannte Funktionen verwenden sollte

Verwenden Sie Lambda-Ausdrücke, wenn:

  • Die Funktion sehr einfach ist (ein Ausdruck)
  • Die Funktion nur einmal oder in einem sehr lokalen Kontext verwendet wird
  • Das Definieren einer benannten Funktion unnötig ausführlich wäre

Verwenden Sie eine benannte Funktion, wenn:

  • Die Funktion komplex ist oder mehrere Anweisungen benötigt
  • Die Funktion an mehreren Stellen wiederverwendet wird
  • Die Funktion zur Klarheit einen beschreibenden Namen braucht
  • Die Funktion eine Docstring benötigt

23.5.5) Lambda-Einschränkungen und Alternativen

Lambda-Ausdrücke haben wichtige Einschränkungen:

python
# ❌ Das funktioniert nicht – lambda kann keine Anweisungen enthalten
# bad_lambda = lambda x: 
#     if x > 0:
#         return x
#     else:
#         return -x
 
# ✅ Verwenden Sie stattdessen einen bedingten Ausdruck
absolute_value = lambda x: x if x > 0 else -x
print(absolute_value(-5))  # Output: 5
print(absolute_value(3))   # Output: 3
 
# ✅ Für mehrere Operationen verwenden Sie eine normale Funktion
def process_and_double(x):
    print(f"Processing: {x}")
    return x * 2
 
result = process_and_double(5)  # Output: Processing: 5
print(result)                    # Output: 10

Lambda-Ausdrücke sind Werkzeuge für bestimmte Situationen. Wenn sie Code klarer und prägnanter machen, verwenden Sie sie. Wenn sie Code schwerer verständlich machen, verwenden Sie stattdessen eine normale benannte Funktion.

23.6) map() und filter() mit einfachen Funktionen verwenden

23.6.1) Die Funktion map()

Die Funktion map() wendet eine gegebene function auf jedes Element eines Iterables (wie einer Liste, eines Tupels oder eines Strings) an und gibt einen Iterator mit den Ergebnissen zurück. Es ist eine Möglichkeit, jedes Element in einer Sammlung zu transformieren, ohne eine explizite Schleife zu schreiben.

python
map(function, iterable, *iterables)

Parameter:

  • function (erforderlich): Eine Funktion, die ein oder mehrere Argumente entgegennimmt, sie verarbeitet und einen Wert zurückgibt. Die Funktion wird für jedes Element in den iterable(s) einmal aufgerufen.
  • iterable (erforderlich): Eine Sequenz (Liste, Tupel, String usw.), deren Elemente an die function übergeben werden.
  • *iterables (optional): Zusätzliche Iterables für eine function mit mehreren Argumenten.

Wenn mehrere Iterables bereitgestellt werden, muss function entsprechend viele Argumente akzeptieren
map() stoppt, wenn das kürzeste Iterable erschöpft ist

Rückgabewert:

Ein map-Objekt (Iterator), das die von der function zurückgegebenen Ergebnisse für jedes Eingabeelement enthält.

Wichtig: Das map-Objekt ist ein Iterator, keine Sequenz wie eine list.

python
# Jede Zahl in einer Liste verdoppeln
numbers = [1, 2, 3, 4, 5]
 
def double(x):
    return x * 2
 
# double auf jede Zahl anwenden
doubled = map(double, numbers)
result = list(doubled)  # map-Objekt (Iterator) in Liste umwandeln
print(result)  # Output: [2, 4, 6, 8, 10]

23.6.2) map() mit Lambda verwenden

Lambda-Ausdrücke funktionieren perfekt mit map() für einfache Transformationen:

python
# Temperaturen von Celsius nach Fahrenheit umrechnen
celsius_temps = [0, 10, 20, 30, 40]
 
fahrenheit_temps = list(map(lambda c: (c * 9/5) + 32, celsius_temps))
print(fahrenheit_temps)  # Output: [32.0, 50.0, 68.0, 86.0, 104.0]

23.6.3) Die Funktion filter()

Die Funktion filter() wendet eine gegebene function auf jedes Element eines iterable an und gibt einen Iterator zurück, der nur die Elemente enthält, für die die Funktion True zurückgibt. Es ist eine Möglichkeit, Elemente aus einer Sammlung auszuwählen, ohne eine explizite Schleife zu schreiben.

python
filter(function, iterable)

Parameter:

  • function: Eine Funktion, die ein Argument entgegennimmt, es auswertet und True oder False zurückgibt. Die Funktion wird für jedes Element im iterable einmal aufgerufen.
  • iterable: Eine Sequenz (Liste, Tupel, String usw.), deren Elemente von der function getestet werden.

Rückgabewert:

Ein filter-Objekt (Iterator), das nur die Elemente enthält, für die die function True zurückgegeben hat.

Wichtig: Das filter-Objekt ist ein Iterator, keine Sequenz wie eine Liste.

Beispiel:

python
# Nur gerade Zahlen behalten
numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
 
def is_even(x):
    return x % 2 == 0
 
# is_even auf jede Zahl anwenden und nur die behalten, die True zurückgeben
even_numbers = filter(is_even, numbers)
result = list(even_numbers)  # filter-Objekt in Liste umwandeln
print(result)  # Output: [2, 4, 6, 8, 10]

23.6.4) filter() mit Lambda verwenden

Lambda-Ausdrücke werden häufig mit filter() für prägnantes Filtern verwendet:

python
# Schüler filtern, die bestanden haben (grade >= 60)
students = [
    {"name": "Alice", "grade": 85},
    {"name": "Bob", "grade": 55},
    {"name": "Charlie", "grade": 92},
    {"name": "Diana", "grade": 48},
    {"name": "Eve", "grade": 73}
]
 
passed = list(filter(lambda s: s["grade"] >= 60, students))
print("Students who passed:")
for student in passed:
    print(f"  {student['name']}: {student['grade']}")
# Output:
#   Alice: 85
#   Charlie: 92
#   Eve: 73

23.6.5) map() und filter() kombinieren

Sie können map()- und filter()-Operationen verketten, um komplexe Transformationen durchzuführen:

python
# Quadrate gerader Zahlen erhalten
numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
 
# Zuerst gerade Zahlen filtern, dann quadrieren
even_numbers = filter(lambda x: x % 2 == 0, numbers)
squared = map(lambda x: x ** 2, even_numbers)
result = list(squared)
print(result)  # Output: [4, 16, 36, 64, 100]

Visueller Vergleich: map() vs filter()

filter() - Behält EINIGE Elemente

Eingabe: [1, 2, 3, 4, 5]

Test: is_even(x)

Ausgabe: [2, 4](gleich oder kürzer)

map() - Transformiert ALLE Elemente

Eingabe: [1, 2, 3, 4, 5]

Anwenden: double(x) = x * 2

Ausgabe: [2, 4, 6, 8, 10](gleiche Länge)

Wichtige Unterschiede:

  • map(): Wendet eine Funktion an, um jedes Element zu transformieren → Ausgabe hat gleiche Länge
  • filter(): Testet jedes Element und behält nur die, die bestehen → Ausgabe hat gleiche oder kürzere Länge

In diesem Kapitel haben wir Pythons leistungsstarke funktionale Programmierfunktionen erkundet. Wir haben gelernt, dass Funktionen First-Class-Objekte sind, die wie jeder andere Wert weitergereicht werden können, was flexible und wiederverwendbare Code-Muster ermöglicht. Wir haben entdeckt, wie Funktionen andere Funktionen zurückgeben können, wodurch Closures entstehen, die sich ihre Umgebung merken. Wir haben Lambda-Ausdrücke für prägnante Funktionsdefinitionen erkundet, und wir haben map() und filter() verwendet, um Sammlungen elegant zu verarbeiten.

Diese Konzepte bilden die Grundlage für fortgeschrittene Python-Programmiertechniken. In Kapitel 38 werden wir auf diesem Wissen aufbauen, um Decorators (decorators) zu meistern, eines der elegantesten Features von Python.


© 2025. Primesoft Co., Ltd.
support@primesoft.ai