Python Language
Kaart functie
Zoeken…
Syntaxis
- map (functie, iterable [, * extra_iterables])
- future_builtins.map (function, iterable [, * addition_iterables])
- itertools.imap (functie, iterabel [, * extra_iterabelen])
parameters
Parameter | Details |
---|---|
functie | functie voor mapping (moet evenveel parameters bevatten als er iterables zijn) ( alleen positioneel ) |
iterable | de functie wordt toegepast op elk element van de iterabele ( alleen positioneel ) |
* additional_iterables | zie iterabel, maar zoveel als je wilt ( optioneel , alleen positioneel ) |
Opmerkingen
Alles wat met map
kan worden gedaan, kan ook met comprehensions
worden gedaan:
list(map(abs, [-1,-2,-3])) # [1, 2, 3]
[abs(i) for i in [-1,-2,-3]] # [1, 2, 3]
Hoewel je zip
nodig hebt als je meerdere iterables hebt:
import operator
alist = [1,2,3]
list(map(operator.add, alist, alist)) # [2, 4, 6]
[i + j for i, j in zip(alist, alist)] # [2, 4, 6]
Lijstbegrippen zijn efficiënt en kunnen in veel gevallen sneller zijn dan map
, dus test de tijden van beide benaderingen als snelheid belangrijk voor u is.
Basisgebruik van map, itertools.imap en future_builtins.map
De kaartfunctie is de eenvoudigste van de ingebouwde Python-functies die worden gebruikt voor functioneel programmeren. map()
past een gespecificeerde functie toe op elk element in een iterabel:
names = ['Fred', 'Wilma', 'Barney']
map(len, names) # map in Python 3.x is a class; its instances are iterable
# Out: <map object at 0x00000198B32E2CF8>
Een Python 3-compatibele map
is opgenomen in de module future_builtins
:
from future_builtins import map # contains a Python 3.x compatible map()
map(len, names) # see below
# Out: <itertools.imap instance at 0x3eb0a20>
Als alternatief kun je in Python 2 imap
van itertools
gebruiken om een generator te krijgen
map(len, names) # map() returns a list
# Out: [4, 5, 6]
from itertools import imap
imap(len, names) # itertools.imap() returns a generator
# Out: <itertools.imap at 0x405ea20>
Het resultaat kan expliciet worden omgezet in een list
om de verschillen tussen Python 2 en 3 te verwijderen:
list(map(len, names))
# Out: [4, 5, 6]
map()
kan worden vervangen door een equivalent lijstbegrip of generatoruitdrukking :
[len(item) for item in names] # equivalent to Python 2.x map()
# Out: [4, 5, 6]
(len(item) for item in names) # equivalent to Python 3.x map()
# Out: <generator object <genexpr> at 0x00000195888D5FC0>
Elke waarde in een iterabel in kaart brengen
U kunt bijvoorbeeld de absolute waarde van elk element nemen:
list(map(abs, (1, -1, 2, -2, 3, -3))) # the call to `list` is unnecessary in 2.x
# Out: [1, 1, 2, 2, 3, 3]
Anonieme functie ondersteunt ook het toewijzen van een lijst:
map(lambda x:x*2, [1, 2, 3, 4, 5])
# Out: [2, 4, 6, 8, 10]
of het omzetten van decimale waarden naar percentages:
def to_percent(num):
return num * 100
list(map(to_percent, [0.95, 0.75, 1.01, 0.1]))
# Out: [95.0, 75.0, 101.0, 10.0]
of dollars omrekenen naar euro's (gegeven een wisselkoers):
from functools import partial
from operator import mul
rate = 0.9 # fictitious exchange rate, 1 dollar = 0.9 euros
dollars = {'under_my_bed': 1000,
'jeans': 45,
'bank': 5000}
sum(map(partial(mul, rate), dollars.values()))
# Out: 5440.5
functools.partial
is een handige manier om parameters van functies te repareren, zodat ze kunnen worden gebruikt met map
plaats van lambda
of aangepaste functies te maken.
Waarden van verschillende iterables in kaart brengen
Bijvoorbeeld het berekenen van het gemiddelde van elk i
element van meerdere iterables:
def average(*args):
return float(sum(args)) / len(args) # cast to float - only mandatory for python 2.x
measurement1 = [100, 111, 99, 97]
measurement2 = [102, 117, 91, 102]
measurement3 = [104, 102, 95, 101]
list(map(average, measurement1, measurement2, measurement3))
# Out: [102.0, 110.0, 95.0, 100.0]
Er zijn verschillende vereisten als er meer dan één iterabel wordt doorgegeven aan de map
afhankelijk van de versie van python:
De functie moet zoveel parameters bevatten als er iterables zijn:
def median_of_three(a, b, c): return sorted((a, b, c))[1] list(map(median_of_three, measurement1, measurement2))
TypeError: median_of_three () ontbreekt 1 vereist positioneel argument: 'c'
list(map(median_of_three, measurement1, measurement2, measurement3, measurement3))
TypeError: median_of_three () neemt 3 positionele argumenten, maar er werden 4 gegeven
map
: de mapping herhaalt zich zolang er nog een iterabel is die nog niet volledig is verbruikt, maar gaat uit vanNone
van de volledig gebruikte iterables:import operator measurement1 = [100, 111, 99, 97] measurement2 = [102, 117] # Calculate difference between elements list(map(operator.sub, measurement1, measurement2))
TypeError: niet-ondersteunde operandtype (n) voor -: 'int' en 'NoneType'
itertools.imap
enfuture_builtins.map
: de toewijzing stopt zodra een iterabele stopt:import operator from itertools import imap measurement1 = [100, 111, 99, 97] measurement2 = [102, 117] # Calculate difference between elements list(imap(operator.sub, measurement1, measurement2)) # Out: [-2, -6] list(imap(operator.sub, measurement2, measurement1)) # Out: [2, 6]
De toewijzing stopt zodra een iterabele stopt:
import operator measurement1 = [100, 111, 99, 97] measurement2 = [102, 117] # Calculate difference between elements list(map(operator.sub, measurement1, measurement2)) # Out: [-2, -6] list(map(operator.sub, measurement2, measurement1)) # Out: [2, 6]
Transponeren met kaart: "None" gebruiken als functieargument (alleen python 2.x)
from itertools import imap
from future_builtins import map as fmap # Different name to highlight differences
image = [[1, 2, 3],
[4, 5, 6],
[7, 8, 9]]
list(map(None, *image))
# Out: [(1, 4, 7), (2, 5, 8), (3, 6, 9)]
list(fmap(None, *image))
# Out: [(1, 4, 7), (2, 5, 8), (3, 6, 9)]
list(imap(None, *image))
# Out: [(1, 4, 7), (2, 5, 8), (3, 6, 9)]
image2 = [[1, 2, 3],
[4, 5],
[7, 8, 9]]
list(map(None, *image2))
# Out: [(1, 4, 7), (2, 5, 8), (3, None, 9)] # Fill missing values with None
list(fmap(None, *image2))
# Out: [(1, 4, 7), (2, 5, 8)] # ignore columns with missing values
list(imap(None, *image2))
# Out: [(1, 4, 7), (2, 5, 8)] # dito
list(map(None, *image))
TypeError: 'NoneType' object kan niet worden opgevraagd
Maar er is een oplossing om vergelijkbare resultaten te hebben:
def conv_to_list(*args):
return list(args)
list(map(conv_to_list, *image))
# Out: [[1, 4, 7], [2, 5, 8], [3, 6, 9]]
Series en parallelle kaarten
map () is een ingebouwde functie, wat betekent dat het overal beschikbaar is zonder dat u een 'import'-instructie hoeft te gebruiken. Het is overal beschikbaar, net als print (). Als je naar voorbeeld 5 kijkt, zie je dat ik een import-statement moest gebruiken voordat ik pretty print kon gebruiken (import pprint). Daarom is pprint geen ingebouwde functie
Series in kaart brengen
In dit geval wordt elk argument van de iterable als argument aan de toewijzingsfunctie in oplopende volgorde geleverd. Dit doet zich voor wanneer we slechts één itereerbare kaart hebben en de toewijzingsfunctie een enkel argument vereist.
voorbeeld 1
insects = ['fly', 'ant', 'beetle', 'cankerworm']
f = lambda x: x + ' is an insect'
print(list(map(f, insects))) # the function defined by f is executed on each item of the iterable insects
resulteert in
['fly is an insect', 'ant is an insect', 'beetle is an insect', 'cankerworm is an insect']
Voorbeeld 2
print(list(map(len, insects))) # the len function is executed each item in the insect list
resulteert in
[3, 3, 6, 10]
Parallelle mapping
In dit geval wordt elk argument van de toewijzingsfunctie parallel getrokken uit alle iterabelen (één uit elke iterabele). Het aantal geleverde iterables moet dus overeenkomen met het aantal argumenten dat de functie vereist.
carnivores = ['lion', 'tiger', 'leopard', 'arctic fox']
herbivores = ['african buffalo', 'moose', 'okapi', 'parakeet']
omnivores = ['chicken', 'dove', 'mouse', 'pig']
def animals(w, x, y, z):
return '{0}, {1}, {2}, and {3} ARE ALL ANIMALS'.format(w.title(), x, y, z)
Voorbeeld 3
# Too many arguments
# observe here that map is trying to pass one item each from each of the four iterables to len. This leads len to complain that
# it is being fed too many arguments
print(list(map(len, insects, carnivores, herbivores, omnivores)))
resulteert in
TypeError: len() takes exactly one argument (4 given)
Voorbeeld 4
# Too few arguments
# observe here that map is suppose to execute animal on individual elements of insects one-by-one. But animals complain when
# it only gets one argument, whereas it was expecting four.
print(list(map(animals, insects)))
resulteert in
TypeError: animals() missing 3 required positional arguments: 'x', 'y', and 'z'
Voorbeeld 5
# here map supplies w, x, y, z with one value from across the list
import pprint
pprint.pprint(list(map(animals, insects, carnivores, herbivores, omnivores)))
resulteert in
['Fly, lion, african buffalo, and chicken ARE ALL ANIMALS',
'Ant, tiger, moose, and dove ARE ALL ANIMALS',
'Beetle, leopard, okapi, and mouse ARE ALL ANIMALS',
'Cankerworm, arctic fox, parakeet, and pig ARE ALL ANIMALS']