Lernpfad
Die Python-Funktion „ reduce() ” kommt aus der Welt der funktionalen Programmierung. Funktionale Programmierung (FP) ist ein Programmieransatz, bei dem Programme Ergebnisse durch die Anwendung von Funktionen auf unveränderliche Daten erzeugen.
Ein gängiges Muster in diesem Stil ist die „Faltung“, die eine Sequenz zu einem einzigen Ergebnis zusammenfasst. Zum Beispiel, wenn du die Zahlenliste [2, 4, 5, 3] durch Addition 14 in aufeinanderfolgenden Schritten zusammenfasst: [2, 4, 5, 3] → [6, 5, 3] → [11, 3] → 14.
reduce() verallgemeinert diese Idee. Es wendet eine binäre Operation auf ein iterierbares Objekt an, bis nur noch das Ergebnis übrig ist.
In diesem Artikel schaue ich mir die wichtigsten Teile von Python „ reduce() ” an und gebe ein paar praktische Beispiele. Wenn du eine Auffrischung der Grundlagen von Python brauchst, schau dir doch mal diese Ressourcen an:
- Python-Slice: Nützliche Methoden für den täglichen Programmieralltag Tutorial zu „ “
- Python für R-Nutzer Kurs
Geschichte
Python hat noch mehr funktionale Programmierfunktionen, wie zum Beispiel map() und filter().
Funktionale Konstrukte wie „ map() “ und „ filter() “ waren in Python 1.0 enthalten. Guido van Rossum mochte sie nicht und meinte, dass „ reduce() “ schwer zu analysieren sei und eine Schleife „ for “ fast immer besser zu lesen sei. In Python 3.0 haben die Entwickler nach PEP 3100 die Funktion ` reduce() ` als integrierte Funktion rausgenommen und sie ins Modul ` functools ` verschoben. Durch die Umstellung auf „ functools “ wurde es quasi zu einem Nischenwerkzeug.
Warum reduce() verwenden?
Meistens finde ich es wahrscheinlich besser, eine integrierte Funktion oder eine Schleife zu verwenden. In manchen Fällen ist „ reduce() “ aber immer noch eine gute Wahl.
- Funktionspipelines. Kette eine (möglicherweise dynamische) Reihe von Transformationen auf saubere Weise aneinander.
- Algebraische Falten. Verwende das für Operationen mit natürlichen Identitätswerten, wie zum Beispiel die Vereinigungsmenge mit der leeren Menge oder Bitmaskenoperationen mit Null.
- Individuelle Falzung ohne Einbau. Definiere deine eigene Zusammenführung auf domänenspezifische Weise, wenn keine integrierte Funktion vorhanden ist.
- Strukturierte Akkumulatoren. Lerne mehrere Zustände gleichzeitig in einer benutzerdefinierten Akkumulatorfunktion.
Wie Python reduce() funktioniert
Schauen wir uns mal an, wie „ reduce() “ funktioniert.
Die grundlegende Funktionssignatur von „ reduce() “ lautet
functools.reduce(function, iterable, [initializer])
Die Funktion reduce() Funktion braucht zwei Argumente und kann noch ein drittes mitbringen.
functionEine binäre Funktion, die sagt, wie man zwei Elemente zusammenfügt.iterableDie zu reduzierende Sequenz oder Iterable, wie zum Beispiel eine Liste oder ein Tupel.initializer(optional): ein Startwert, um die Funktion zu initialisieren.
Schritt-für-Schritt-Beispiel:
- [1, 3, 2, 7] → [4, 2, 7].
- [4, 2, 7] → [6, 7].
- [6, 7] → [13].
Das Endergebnis ist 13.
Einfache Beispiele für reduce()
Die folgenden einfachen Beispiele zeigen, wie man „ reduce() “ benutzt.
from functools import reduce
numbers = [2, 4, 6]
product = reduce(lambda x, y: x * y, numbers) # ((2 x 4) x 6) = 8 x 6 = 48
min_value = reduce(lambda x, y: x if x < y else y, numbers) # 2
words = ['dog', 'cat', 'tree', 'pony']
str_concat = reduce(lambda x, y: x + y, words) # "dogcattreepony"
Initialisierer
Ohne Initialisierer nimmt „ reduce() “ das erste Element des iterierbaren Objekts als Startwert. Wenn das Iterable leer ist, löst „ reduce() “ einen „ TypeError “ aus. Um den Code stabil zu machen, gib einen Initialisierer an, der das Verhalten bei leeren Eingaben festlegt.
from functools import reduce
words = []
# Error: reduce() of empty iterable with no initial value
str_concat = reduce(lambda x, y: x + y, words)
# Correct: use empty string initializer
str_concat = reduce(lambda x, y: x + y, words, "")
Initialisierer füllen ein Ergebnis auch mit einem leeren Container. Du kannst zum Beispiel Wörter zu einer flachen Liste von Zeichen zusammenfügen.
from functools import reduce
words = ['reduce', 'is', 'fun']
chars_list = reduce(lambda acc, word: acc + list(word), words, [])
print(chars_list) # ['r', 'e', 'd', 'u', 'c', 'e', 'i', 's', 'f', 'u', 'n']
Um Python und die Datenbearbeitung weiter zu erkunden, habe ich hier ein paar Optionen, die ich empfehlen kann.
- Einführung in den Kurs „Datenimport in Python“
- Datenbearbeitung in Python – Lernpfad
- Daten mit pandas in Python umgestalten – Spickzettel
- Kurs „Dimensionsreduktion in Python”
- Datenvorverarbeitung: Ein kompletter Leitfaden mit Python-Beispielen Blog „ ”
Den Reducer definieren
Bisher haben wir Lambda-Funktionen benutzt, um den binären Operator zu definieren.
Du kannst auch Operatoren aus dem Modul „ operator “ verwenden. Das Modul „ operator “ ( ) hat Funktionsversionen von gängigen Operatoren und Methodenaufrufen. Anstelle von x + y könnte man zum Beispiel auch operator.add(x, y) schreiben. Damit kannst du vordefinierte (und effiziente) Operatoren an ` reduce(` übergeben, ohne dass du ein Lambda schreiben musst.
from functools import reduce
import operator as op
numbers = [2, 4, 6]
total = reduce(op.add, numbers, 0) # instead of reduce(lambda x,y: x + y, numbers)
Eine dritte Möglichkeit ist, eine eigene Funktion zu schreiben. Das ist eine gute Option, wenn es keinen vordefinierten Operator gibt oder die Funktion für ein Lambda zu kompliziert ist.
Angenommen, du willst Duplikate aus einer Liste entfernen, aber die Reihenfolge der ersten Nennung beibehalten. Du könntest einen Reducer definieren, der ein Element nur dann an eine Liste anhängt, wenn es vorher noch nicht aufgetaucht ist.
from functools import reduce
items = ['the', 'wild', 'wild', 'world', 'is', 'the', 'wide', 'world', 'is', 'the', 'world']
def dedup(acc, x):
if x not in acc: # O(n) membership test
acc.append(x)
return acc
unique = reduce(dedup, items, []) # ['the', 'wild', 'world', 'is', 'wide']
Weitere Ideen zum Entfernen von Duplikaten findest du in diesem Tutorial.
Leistung von Python reduce()
reduce() hat mit Leistungsproblemen zu tun.
Funktionsaufruf-Overhead
Python- reduce() ruft unsere Funktion einmal für jedes Element auf. Bei einer Liste mit einer Million Elementen bedeutet das eine Million Funktionsaufrufe, von denen jeder einen Frame erstellt, Argumente verarbeitet und Referenzzahlen aktualisiert. Das macht den Aufwand echt groß.
Im Gegensatz dazu macht ein eingebautes Element wie „ sum “ einen einzigen Aufruf in einer C-Funktion und führt die Millionen Additionen innerhalb der C-Schleife durch. Dieser Unterschied kann die integrierten Befehle um ein Vielfaches schneller machen.
Probleme mit Cache-Lokalität und CPU-Effizienz
Reduce hat auch Probleme mit Cache-Lokalität und CPU-Effizienz.
Eine moderne CPU kann mehrere Milliarden Befehle pro Sekunde ausführen, aber der Zugriff auf den RAM ist um ein Vielfaches langsamer. Um das auszugleichen, haben moderne CPUsCaches mit mehreren Ebenen( , L1, L2, L3), die Daten für einen schnellen Zugriff speichern.
Diese Caches nutzen zwei Muster aus.
- Zeitliche Lokalität Daten, die kürzlich benutzt wurden, werden wahrscheinlich wieder benutzt werden.
- Raumbezogene Nähe Daten in der Nähe einer kürzlich verwendeten Adresse werden wahrscheinlich bald wieder gebraucht.
Im Gegensatz dazu muss man bei jedem Schritt von „ reduce() “ nach dem nächsten Element suchen und Python-Funktionen aufrufen, was die Lokalität stört und die CPU ausbremst. Eingebaute und vektorisierte Funktionen umgehen dieses Problem, indem sie über enge C-Schleifen laufen.
Wenn du eine Auffrischung zum Schreiben von idiomatischem und effizientem Python-Code brauchst, schau dir Folgendes an:
- 5 Tipps zum Schreiben von idiomatischem Pandas-Code Tutorial
- Effizienten Python-Code schreiben Kurs
- Effizienten Code mit pandas schreiben Kurs
Alternativen zu Python reduce()
Einbauten:
- Optimierter C-Code. Built-ins laufen in optimiertem C-Code, nicht in Python. Dadurch wird der Aufwand vermieden, der bei „
reduce()“ anfällt. Dieser Geschwindigkeitsvorteil macht sich bei großen Eingaben besonders bemerkbar. - Lesbarkeit. Eingebaute Funktionen haben beschreibende Namen (
sum,min), sodass ihr Zweck klar ist. Ein Aufruf von „reduce()“ lässt dich die Funktion analysieren, die gefaltet wird.
Loops:
- Leistung. Schleifen laufen normalerweise langsamer als integrierte Funktionen, aber schneller als „
reduce()“. - Lesbarkeit. Genau wie Built-ins sind Schleifen meistens besser zu lesen als „
reduce()“. Ein Aufruf von „reduce()“ zwingt dich dazu, eine funktionale Anweisung zu analysieren, während eine Schleife eher Python-typisch ist.
itertools.accumulate()
Die Python-Bibliothek „ itertools ” hat eine Reihe von leistungsstarken Iteratoren wie „ count() ”, „ product() ” und „ combinations() ”. Eine nützliche Funktion von „ itertools “ ist „ itertools.accumulate() “. Genau wie „ reduce() “ wendet es eine Funktion auf ein iterierbares Objekt an. accumulate() speichert aber nicht nur das Endergebnis, sondern auch Zwischenwerte der Berechnung.
Zum Beispiel:
import itertools, operator
from functools import reduce
list(itertools.accumulate([1, 2, 3, 4], initial=0)) # [0, 1, 3, 6, 10]
reduce(operator.add, [1, 2, 3, 4], 0) # 10
Die Funktion „Akkumulieren“ ist praktisch, wenn du laufende Summen oder Minimal-/Maximalwerte brauchst. Du möchtest vielleicht wissen, wie hoch die höchste Temperatur im Monat war.
Häufige Probleme bei der Verwendung von reduce()
Wenn du reduce() benutzt, denk an die folgenden Fallstricke.
- Nimm lieber einfachere Alternativen wie Einbauten oder Schleifen. Heb dir „
reduce()“ für den Fall auf, dass du es wirklich brauchst. - Leere iterierbare Objekte verarbeiten. Benutze immer einen passenden Initialisierer, um Fehler bei leeren Eingaben zu vermeiden.
- Pass auf Speicherprobleme auf. Versuche nicht, „
reduce()” in Situationen zu zwängen, in denen ein Generator oder ein Streaming-Ansatz effizienter wäre. - Vermeide knifflige Lambdas. Benutz die Funktionen aus dem Modul „
operator“, wenn du kannst. Lambdas können, vor allem bei nicht-assoziativen Operationen, die Übersichtlichkeit beeinträchtigen. - Sei lieber klar als clever.
Python reduce() – Best Practices und Richtlinien
Wie bei jedem Tool gibt es auch bei „ reduce() “ bewährte Vorgehensweisen. Wenn du dich für reduce() entschieden hast, findest du hier ein paar Tipps zur Nutzung.
Entwerfe zuerst den Reduzierer.
- Beschreib den Vertrag in einem Satz. „Füge Wörterbuchschlüssel zusammen, indem du die Anzahl pro Schlüssel addierst.“
- Halt es möglichst assoziativ. So kannst du leichter parallelisieren und testen.
- Finde dein Identitätselement und benutze es als Initialisierer. Zum Beispiel ist die Identität für die Summe 0. Für
minist esmath.infund fürset unionist esset(). So bleibt der Code stabil und frei von „TypeErrors“.
Halte es einfach und verständlich
- Eine klare Sache. Keine Nebenwirkungen.
- Gib dem Reduzierer einen aussagekräftigen Namen.
Dokument
- Schreib im Docstring das Identitätselement und das Verhalten bei leeren Eingaben, die Assoziativitätsannahme und die Fehlerbehandlung auf.
Test
- Unit-Tests für Randfälle: leere Iterable, gemischte Typen, Extremwerte.
- Testet die Assoziativität.
Leistung überwachen
- Vergleich kleine und große Eingaben. Vergleich Benchmarks mit integrierten Funktionen und Schleifen.
- Wenn es auf Geschwindigkeit ankommt, solltest du Vorverarbeitung, Batch-Verarbeitung und die Verlagerung rechenintensiver Aufgaben auf NumPy oder pandas in Betracht ziehen.
Fortgeschrittene Anwendungen und praktische Anwendungsfälle für Python reduce()
Angesichts der Nachteile könnte man meinen, dass „ reduce() “ keinen echten Wert hat. Im Gegenteil, „ reduce() “ hat viele coole Anwendungsfälle.
- Verarbeitung verschachtelter Strukturen
- Datenbankähnliche Vorgänge
- Datenverarbeitungs-Pipelines
- MapReduce-Anwendungen
Verarbeitung verschachtelter Strukturen
Reduce bietet eine saubere Möglichkeit, verschachtelte Datenstrukturen wie JSON-Objekte zu durchlaufen, indem es eine Folge von Schlüsseln zu aufeinanderfolgenden Suchvorgängen zusammenfasst.
import json
from functools import reduce
import operator
data = json.loads('''
{
"user": {
"id": "ABC123",
"name": "Alice",
"email": "alice@example.com",
"profile": {
"address": {
"city": "San Francisco",
"zip": "94103"
},
"age": 34,
"skills": ["Python", "Data Science", "Machine Learning"]
}
}
}
''')
# Example lookups with reduce + operator.getitem
city = reduce(operator.getitem, ["user", "profile", "address", "city"], data)
print(city) # "San Francisco"
user_id = reduce(operator.getitem, ["user", "id"], data)
print(user_id) # "ABC123"
age = reduce(operator.getitem, ["user", "profile", "age"], data)
print(age) # 34
Hier macht es Sinn, „ reduce() “ zu verwenden. Das JSON ist ziemlich verschachtelt: user → profile → address → city. Anstatt Lookups manuell zu verketten, stell den Pfad als Liste von Schlüsseln dar. Dann benutz „ reduce(operator.getitem, path, data) “, um es zu durchlaufen. Dadurch bleibt der Code allgemein, verständlich und wiederverwendbar.
Datenverarbeitungs-Pipelines
Reduce kann Datenverarbeitungs-Pipelines steuern, indem es Daten durch eine Reihe von Transformationen schickt. Jede Funktion macht einen Schritt, und die Pipeline kommt, wenn man sie der Reihe nach anwendet. Hier ist eine Spielzeug-Pipeline, die eine Textzeichenfolge vorverarbeitet, bevor sie in ein NLP-Modell eingespeist wird.
from functools import reduce
import re
# Define preprocessing steps
def strip_punctuation(s):
return re.sub(r"[^\w\s]", "", s)
def to_lower(s):
return s.lower()
def remove_stopwords(s):
stops = {"the", "is", "a", "of"}
return " ".join(word for word in s.split() if word not in stops)
def stem_words(s):
# trivial "stemmer": cut off 'ing'
return " ".join(word[:-3] if word.endswith("ing") else word for word in s.split())
pipeline = [
strip_punctuation,
to_lower,
remove_stopwords,
stem_words,
]
# Input data
text = "The quick brown fox is Jumping over a log."
# Apply pipeline with reduce
processed = reduce(lambda acc, f: f(acc), pipeline, text)
print(processed) # quick brown fox jump over log
Fehlerbehandlung in komplizierten Anwendungen
Komm, wir schauen uns nochmal das Beispiel mit dem verschachtelten JSON an. Im Moment löst der direkte Aufruf von reduce(operator.getitem, …) einen Fehler vom Typ „ KeyError “ oder „ TypeError “ aus, wenn ein Schlüssel fehlt oder wenn ein Nicht-Dict gefunden wird. Um den Code sicherer zu machen, definier eine Hilfsfunktion, die operator.getitem in einen try/except-Block einbindet und bei einem Fehler einen Standardwert zurückgibt.
Hier ist eine Idee für die Hilfsfunktion.
def deep_get(data, keys, default=None):
"""Traverse nested dicts/lists safely with reduce."""
try:
return reduce(operator.getitem, keys, data)
except (KeyError, IndexError, TypeError):
return default
Jetzt änderst du die Beispiel-Lookups, damit sie unsere neue Funktion anstelle einer unwrapped verwenden. reduce()
# Example lookups
city = deep_get(data, ["user", "profile", "address", "city"], default="Unknown City")
print(city) # "San Francisco"
user_id = deep_get(data, ["user", "id"], default="N/A")
print(user_id) # "ABC123"
age = deep_get(data, ["user", "profile", "age"], default="N/A")
print(age) # 34
# Example with missing key
phone = deep_get(data, ["user", "profile", "phone"], default="No phone")
print(phone) # "No phone"
Mehrstufige Datenumwandlungen mit map() und filter()
Du kannst „ reduce() “ mit anderen praktischen Tools wie „ map() “ und „ filter() “ kombinieren, um mehrstufige Datenumwandlungen zu erstellen. Hier ist unsere frühere NLP-Vorverarbeitungs-Pipeline, die funktional geschrieben wurde.
from functools import reduce
import re
# Define preprocessing steps
def strip_punctuation(s):
return re.sub(r"[^\w\s]", "", s)
def to_lower(s):
return " ".join(map(str.lower, s.split()))
def remove_stopwords(s):
stops = {"the", "is", "a", "of"}
return " ".join(filter(lambda w: w not in stops, s.split()))
def stem_words(s):
# trivial "stemmer": cut off 'ing'
return " ".join(map(lambda w: w[:-3] if w.endswith("ing") else w, s.split()))
# Pipeline of transformations
pipeline = [
strip_punctuation,
to_lower,
remove_stopwords,
stem_words,
]
# Input data
text = "The quick brown fox is Jumping over a log."
# Apply pipeline with reduce
processed = reduce(lambda acc, f: f(acc), pipeline, text)
print(processed) # quick brown fox jump over log
Die Transformationen sind:
- Entferne die Satzzeichen. „Der schnelle braune Fuchs springt über einen Baumstamm.“ → „Der schnelle braune Fuchs springt über einen Baumstamm.“
- Kleinbuchstaben
„Der schnelle braune Fuchs springt über einen Baumstamm“ → „Der schnelle braune Fuchs springt über einen Baumstamm“
- Stoppwörter rausnehmen. „Der schnelle braune Fuchs springt über einen Baumstamm“ → „schneller brauner Fuchs springt über Baumstamm“
- Stammwörter
„Schneller brauner Fuchs springt über Baumstamm“ → „Schneller brauner Fuchs springt über Baumstamm“
Um mehr über funktionale Programmierung und Vektorisierung zu erfahren, check mal diese DataCamp-Artikel aus.
- Python filter(): Behalte, was du brauchst – Tutorial
- Groupby, split-apply-combine und pandas – Tutorial
- Pandas Apply Tutorial – Tutorial
Integration in das moderne Python-Ökosystem
Um „ reduce() “ gut zu nutzen, ist es hilfreich zu verstehen, wie es in das moderne Python-Ökosystem passt. Schauen wir mal genauer, wie es mit NumPy und pandas zusammenpasst, wie es parallele und verteilte Systeme unterstützt und wie es mit modernen Tools wie statischen Analysatoren zusammenarbeitet.
numpy und pandas
NumPy und pandas laufen mit optimiertem C-Code, also versuch nicht, ihre Funktionen mit reduce() zu duplizieren. reduce() ist aber eine gute Wahl für Pipelines mit dynamischen Schritten. Du kannst zum Beispiel mehrere NumPy-Transformationen auf ein Array anwenden.
from functools import reduce
import numpy as np
def standardize(x):
return (x - x.mean()) / (x.std() + 1e-9)
def clip(x):
return np.clip(x, 0, 1)
def log(x):
return np.log1p(x)
x = np.array([1, 500, 40.5, 100, 250.45])
funcs = [standardize, clip, log]
y = reduce(lambda a, f: f(a), funcs, x) # x is ndarray
Parallele und verteilte Rechenumgebungen
Reduzieren ist echt wichtig bei parallelen und verteilten Rechenumgebungen. Diese Systeme teilen einen Datensatz in Teile auf, bearbeiten diese Teile gleichzeitig und setzen dann die Teilergebnisse zu einer Antwort zusammen. Der Schritt „kombinieren“ ist die Reduktion.
Damit die Reduzierung in einem Cluster richtig funktioniert, musst du sicherstellen, dass die folgenden Bedingungen erfüllt sind.
- Assoziativität. Die Operation muss unabhängig von der Gruppierung immer das gleiche Ergebnis liefern. Dadurch können Teilergebnisse in beliebiger Reihenfolge im Netzwerk zusammengeführt werden.
- Identitätselement. Die Operation muss einen Initialisierer haben, der das Endergebnis nicht beeinflusst. Das sorgt dafür, dass alles richtig läuft, wenn Partitionen leer sind oder unterschiedliche Größen haben.
Wenn diese Eigenschaften nicht zutreffen, werden Reduktionen langsam (weil sie nicht sicher parallelisiert werden können) oder fehlerhaft (weil die Ergebnisse von der Auswertungsreihenfolge abhängen).
Dieser Prozess braucht eine assoziative Operation und eine klare Identität. Sonst kriegst du langsamen Code oder falsche Ergebnisse.
Statische Analyse-Tools
Ein statischer Analysator (wie mypy, Pyright, ruff oder bandit) ist ein Tool, das Code checkt, ohne ihn auszuführen. Diese Tools finden Fehler, sorgen dafür, dass Stilregeln eingehalten werden, und checken, ob alles richtig geschrieben ist.
Statische Analysatoren haben Probleme mit „ reduce() “. Beim Faltvorgang kann der Akkumulatortyp vom Elementtyp abweichen, und die Typinferenz wird kompliziert.
Schau dir mal diesen Code an.
from functools import reduce
def add_chars(acc, word):
acc.extend(word) # extend adds each character of the string
return acc
chars = reduce(add_chars, ["hi", "ok"], [])
print(chars) # ['h', 'i', 'o', 'k']
Auch wenn dieser Code gut läuft, könnte ein statischer Analysator ein paar Probleme melden.
- Der Elementtyp des Initialisierers [] ist nicht eindeutig.
- Analysatoren könnten davon ausgehen, dass die Akkumulator- und Elementtypen übereinstimmen.
Um den Code für Leute und Analysatoren verständlicher zu machen, füge Typ-Hinweise hinzu.
from functools import reduce
from typing import List
def add_chars(acc: List[str], word: str) -> List[str]:
acc.extend(word) # extend adds each character of the string
return acc
chars: List[str] = reduce(add_chars, ["hi", "ok"], [])
print(chars) # ['h', 'i', 'o', 'k']
Jetzt zeigt der Reduzierer ganz klar
- Der Akkumulator ist ein
List[str]. - Jedes Element ist ein „
str“. - Der Rückgabetyp ist ein „
list[str]“.
Mit diesen Tipps können statische Analysatoren den Code gründlich checken.
Fazit
Reduce kommt aus der funktionalen Programmierung, wo das Zusammenfassen von Sammlungen zu einem einzigen Ergebnis eine Kernidee ist. Auch wenn es in Python nicht mehr das beste Tool ist, hat es trotzdem seinen Platz. Wenn du flexible Pipelines, benutzerdefinierte Falzungen oder Vorgänge brauchst, die sich nicht sauber auf vorhandene Funktionen abbilden lassen, ist „ reduce() “ ein echt starkes Tool. Wenn man es richtig einsetzt, passt es super ins Python-Ökosystem und ist in den richtigen Situationen echt praktisch.
Ein paar nützliche Links zu Python, die du vielleicht hilfreich findest.
Python reduce() – Häufig gestellte Fragen
Was macht die Funktion reduce()?
Es nimmt immer wieder eine Funktion mit zwei Argumenten an einem iterierbaren Objekt vor, um es auf ein einziges Ergebnis zu reduzieren.
Wo ist reduce() definiert?
Vor Version 3 war das eine eingebaute Funktion. Seitdem ist es im Modul „ functools “ zu finden.
Welche Funktionen soll ich an reduce() übergeben?
Einfache, assoziative und gut dokumentierte Funktionen. Vermeide Nebenwirkungen und nicht-assoziative Logik.
Wie ist es im Vergleich zu itertools.accumulate()?
reduce() gibt nur das Endergebnis zurück, accumulate() gibt alle Zwischenergebnisse aus.
Wann sollte ich einen Initialisierer benutzen?
Benutze einen Initialisierer, wenn das Iterable leer sein könnte.

