Hintergrund
Die Funktion map() stammt aus der funktionalen Programmierung (schon aus Lisp), ihr Zweck ist es, eine Funktion auf jedes Element einer Sequenz anzuwenden und ein neues iterierbares Objekt mit den Ergebnissen zurückzugeben. In Python entstand sie lange vor der Einführung von Generator- und Listen-Ausdrücken, wird aber immer noch häufig verwendet, insbesondere in großen Datenverarbeitungs-Pipelines.
Problem
Wenn jedes Element einer Sammlung nach einer bestimmten Regel geändert werden soll, werden Lösungen wie for-Schleifen schnell unhandlich und weniger lesbar. Listen-Ausdrücke und map() ermöglichen es, die Absicht kompakt auszudrücken. Es ist jedoch wichtig, die Unterschiede dieser Ansätze zu verstehen, um das richtige Werkzeug auszuwählen.
Lösung
map(func, iterable) erstellt einen faulen Iterator, in dem die Elemente der ursprünglichen Sequenz durch die Funktion func transformiert werden.map-Objekt die Elemente nicht sofort, sondern arbeitet faul.def square(x): return x * x squares = map(square, [1, 2, 3]) print(list(squares)) # [1, 4, 9]
Der Listen-Ausdruck [square(x) for x in [1, 2, 3]] macht dasselbe, gibt aber sofort eine Liste zurück, während der Generator-Ausdruck (square(x) for x in [1, 2, 3]) ein fauler Generator ist.
Wichtige Merkmale:
Gibt map() in Python 3 eine Liste zurück?
Nein, seit Python 3 gibt map() kein Liste, sondern einen faulen Iterator zurück. Um eine Liste zu erhalten, muss das Ergebnis manuell in list() eingewickelt werden.
res = map(str.upper, ['a', 'b']) print(res) # <map object ...> print(list(res)) # ['A', 'B']
Kann man mit map() eine Filterbedingung innerhalb der Funktion hinzufügen?
Nein, map() filtert keine Elemente, sondern wandelt sie nur um. Für die Filterung verwenden Sie filter() oder einen Listen-Ausdruck:
result = map(str.upper, ['a', 'b', None]) # Wenn None ankommt, ruft map den Fehler str.upper(None) auf # filter hilft, None vor map zu entfernen
Kann man mit map() gleichzeitig zwei Sequenzen durchlaufen?
Ja, map() kann eine beliebige Anzahl von Sequenzen akzeptieren, und die Transformationsfunktion muss die gleiche Anzahl von Argumenten akzeptieren:
x = [1, 2, 3] y = [10, 20, 30] result = map(lambda a, b: a + b, x, y) print(list(result)) # [11, 22, 33]
Ein Entwickler erwartet sofort eine Liste:
mapped = map(abs, [-1, -2, -3]) print(mapped[1]) # TypeError: 'map' object is not subscriptable
Vorteile:
Nachteile:
Verwendung von Generator-Ausdrücken zur Filterung und map() zur Umwandlung:
nums = range(-5, 6) positives = (x for x in nums if x > 0) sq = map(lambda n: n * n, positives) print(list(sq)) # [1, 4, 9, 16, 25, 36]
Vorteile:
Nachteile: