Achtergrond
De functie map() komt uit de functionele programmering (ook uit Lisp), het doel is om een functie toe te passen op elk element van een reeks met het retourneren van een nieuw iterable object met de resultaten. In Python is het lange tijd voorgekomen voordat generator- en lijst-comprehensies verschenen, maar het wordt nog steeds veel gebruikt, vooral in grote data-verwerkingspijplijnen.
Probleem
Als elk element van een collectie op een bepaalde manier moet worden gewijzigd, worden oplossingen in de vorm van for-lussen snel omslachtig en minder leesbaar. Lijst-comprehensies en map() stellen ons in staat om de intentie compact uit te drukken. Het is belangrijk om de verschillen tussen deze benaderingen te begrijpen, zodat we het juiste instrument kunnen kiezen.
Oplossing
map(func, iterable) creëert een luie iterator, waarin de elementen van de oorspronkelijke reeks worden getransformeerd door de functie funcmap de elementen niet onmiddellijk uit, maar werkt het luidef square(x): return x * x squares = map(square, [1, 2, 3]) print(list(squares)) # [1, 4, 9]
Een lijst-comprehensie [square(x) for x in [1, 2, 3]] doet hetzelfde, maar retourneert onmiddellijk een lijst, terwijl een generator-expressie (square(x) for x in [1, 2, 3]) een luie generator is.
Belangrijke kenmerken:
Geeft map() een lijst terug in Python 3?
Nee, vanaf Python 3 retourneert map() geen lijst, maar een luie iterator. Om een lijst te krijgen, moet je het resultaat handmatig in list() wikkelen.
res = map(str.upper, ['a', 'b']) print(res) # <map object ...> print(list(res)) # ['A', 'B']
Kan ik een filtervoorwaarde binnen de functie met map() toevoegen?
Nee, map() filtert geen elementen, alleen transformeert het. Gebruik filter() of een lijst-comprehensie voor filtratie:
result = map(str.upper, ['a', 'b', None]) # Als er een None binnenkomt, zal map een fout oproepen bij het aanroepen van str.upper(None) # filter helpt om None voor map te verwijderen
Kan ik met map() tegelijkertijd twee reeksen doorlopen?
Ja, map() kan een willekeurig aantal reeksen aan, en de transformeerfunctie moet evenveel argumenten aannemen:
x = [1, 2, 3] y = [10, 20, 30] result = map(lambda a, b: a + b, x, y) print(list(result)) # [11, 22, 33]
Een ontwikkelaar verwacht onmiddellijk een lijst te krijgen:
mapped = map(abs, [-1, -2, -3]) print(mapped[1]) # TypeError: 'map' object is not subscriptable
Voordelen:
Nadelen:
Gebruik van een generator-expressie voor filtratie en map() voor transformatie:
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]
Voordelen:
Nadelen: