Python Language
Kartfunktion
Sök…
Syntax
- karta (funktion, iterable [, * extra_iterables])
- future_builtins.map (funktion, iterable [, * extra_iterables])
- itertools.imap (funktion, iterable [, * extra_iterables])
parametrar
Parameter | detaljer |
---|---|
fungera | funktion för kartläggning (måste ta så många parametrar som det finns iterables) (endast positionellt ) |
iterable | funktionen tillämpas på varje element i det iterable (endast positionellt ) |
* additional_iterables | se iterable, men så många du vill ( valfritt , endast positionellt ) |
Anmärkningar
Allt som kan göras med map
kan också göras med comprehensions
:
list(map(abs, [-1,-2,-3])) # [1, 2, 3]
[abs(i) for i in [-1,-2,-3]] # [1, 2, 3]
Även om du skulle behöva zip
om du har flera iterables:
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]
Listförståelser är effektiva och kan vara snabbare än map
i många fall, så testa tiderna för båda metoderna om hastighet är viktig för dig.
Grundläggande användning av karta, itertools.imap och future_builtins.map
Kartfunktionen är den enklaste bland Python-inbyggda apparater som används för funktionell programmering. map()
tillämpar en specificerad funktion på varje element i en iterable:
names = ['Fred', 'Wilma', 'Barney']
map(len, names) # map in Python 3.x is a class; its instances are iterable
# Out: <map object at 0x00000198B32E2CF8>
En Python 3-kompatibel map
ingår i future_builtins
modulen:
from future_builtins import map # contains a Python 3.x compatible map()
map(len, names) # see below
# Out: <itertools.imap instance at 0x3eb0a20>
Alternativt kan man i Python 2 använda imap
från itertools
att få en generator
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>
Resultatet kan uttryckligen konverteras till en list
att ta bort skillnaderna mellan Python 2 och 3:
list(map(len, names))
# Out: [4, 5, 6]
map()
kan ersättas med en motsvarande listaförståelse eller generatoruttryck :
[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>
Kartlägga varje värde i en iterable
Till exempel kan du ta absolutvärdet för varje element:
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]
Anonym funktion stödjer också för att kartlägga en lista:
map(lambda x:x*2, [1, 2, 3, 4, 5])
# Out: [2, 4, 6, 8, 10]
eller konvertera decimalvärden till procenttal:
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]
eller konvertera dollar till euro (med tanke på en växelkurs):
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
är ett bekvämt sätt att fixa parametrar för funktioner så att de kan användas med map
istället för att använda lambda
eller skapa anpassade funktioner.
Kartlägga värden för olika iterables
Till exempel att beräkna medelvärdet för varje i
element i flera 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]
Det finns olika krav om mer än en iterable skickas till map
beroende på versionen av python:
Funktionen måste ta så många parametrar som det finns iterables:
def median_of_three(a, b, c): return sorted((a, b, c))[1] list(map(median_of_three, measurement1, measurement2))
TypeError: median_of_three () saknas 1 obligatoriskt positionsargument: 'c'
list(map(median_of_three, measurement1, measurement2, measurement3, measurement3))
TypeError: median_of_three () tar 3 positionsargument men 4 gavs
map
: Kartläggningen iterates så länge en iterable fortfarande inte är helt konsumerad men antarNone
från de helt konsumerade iterables:import operator measurement1 = [100, 111, 99, 97] measurement2 = [102, 117] # Calculate difference between elements list(map(operator.sub, measurement1, measurement2))
TypeError: operandtyp (er) som inte stöds för -: 'int' och 'NoneType'
itertools.imap
ochfuture_builtins.map
: Kartläggningen stannar så snart en iterable slutar: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]
Kartläggningen stoppar så snart en iterable slutar:
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]
Transponering med karta: Använd "Ingen" som funktionsargument (endast 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' -objektet kan inte kallas
Men det finns en lösning med liknande resultat:
def conv_to_list(*args):
return list(args)
list(map(conv_to_list, *image))
# Out: [[1, 4, 7], [2, 5, 8], [3, 6, 9]]
Serier och parallellkartläggning
map () är en inbyggd funktion, vilket innebär att den finns överallt utan att behöva använda ett "import" -förklaring. Det finns överallt precis som tryck () Om du tittar på exempel 5 ser du att jag var tvungen att använda ett importmeddelande innan jag kunde använda vackert tryck (importera pprint). Således är inte utskrift en inbyggd funktion
Seriekartläggning
I detta fall tillhandahålls varje argument i den iterable som argument till mappningsfunktionen i stigande ordning. Detta uppstår när vi bara har en iterable att kartlägga och kartläggningsfunktionen kräver ett enda argument.
Exempel 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
resulterar i
['fly is an insect', 'ant is an insect', 'beetle is an insect', 'cankerworm is an insect']
Exempel 2
print(list(map(len, insects))) # the len function is executed each item in the insect list
resulterar i
[3, 3, 6, 10]
Parallell kartläggning
I detta fall dras varje argument för mappningsfunktionen parallellt över alla iterables (ett från varje iterable). Således måste antalet iterables som levereras matcha antalet argument som krävs av funktionen.
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)
Exempel 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)))
resulterar i
TypeError: len() takes exactly one argument (4 given)
Exempel 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)))
resulterar i
TypeError: animals() missing 3 required positional arguments: 'x', 'y', and 'z'
Exempel 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)))
resulterar i
['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']