Python Language
Funzione mappa
Ricerca…
Sintassi
- map (function, iterable [, * additional_iterables])
- future_builtins.map (funzione, iterabile [, * additional_iterables])
- itertools.imap (function, iterable [, * additional_iterables])
Parametri
Parametro | Dettagli |
---|---|
funzione | funzione per la mappatura (deve prendere tutti i parametri quanti sono i iterabili) ( solo posizionali ) |
iterabile | la funzione è applicata a ciascun elemento del iterabile ( solo posizionale ) |
* additional_iterables | vedi iterabile, ma quanti ne vuoi ( opzionale , solo posizionale ) |
Osservazioni
Tutto ciò che può essere fatto con la map
può anche essere fatto con le comprehensions
:
list(map(abs, [-1,-2,-3])) # [1, 2, 3]
[abs(i) for i in [-1,-2,-3]] # [1, 2, 3]
Anche se avresti bisogno di zip
se hai più iterabili:
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]
La comprensione delle liste è efficiente e può essere più veloce della map
in molti casi, quindi prova i tempi di entrambi gli approcci se la velocità è importante per te.
Uso di base della mappa, itertools.imap e future_builtins.map
La funzione map è la più semplice tra i built-in Python utilizzati per la programmazione funzionale. map()
applica una funzione specificata a ciascun elemento in un iterabile:
names = ['Fred', 'Wilma', 'Barney']
map(len, names) # map in Python 3.x is a class; its instances are iterable
# Out: <map object at 0x00000198B32E2CF8>
Una map
compatibile con Python 3 è inclusa nel modulo 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>
In alternativa, in Python 2 si può usare imap
da itertools
per ottenere un generatore
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>
Il risultato può essere convertito esplicitamente in una list
per rimuovere le differenze tra Python 2 e 3:
list(map(len, names))
# Out: [4, 5, 6]
map()
può essere sostituito da una comprensione di lista equivalente o un'espressione di generatore :
[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>
Mappare ciascun valore in un iterabile
Ad esempio, puoi prendere il valore assoluto di ogni elemento:
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]
La funzione anonima supporta anche la mappatura di un elenco:
map(lambda x:x*2, [1, 2, 3, 4, 5])
# Out: [2, 4, 6, 8, 10]
o conversione dei valori decimali in percentuali:
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]
o convertire dollari in euro (dato un tasso di cambio):
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
è un modo conveniente per fissare i parametri delle funzioni in modo che possano essere utilizzate con la map
anziché utilizzare lambda
o creare funzioni personalizzate.
Mappatura dei valori di diversi iterabili
Ad esempio, calcolando la media di ogni elemento i
-esimo di più iterabili:
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]
Ci sono diversi requisiti se più di un iterabile viene passato alla map
seconda della versione di python:
La funzione deve prendere tutti i parametri quanti sono i iterabili:
def median_of_three(a, b, c): return sorted((a, b, c))[1] list(map(median_of_three, measurement1, measurement2))
TypeError: median_of_three () mancante 1 argomento posizionale richiesto: 'c'
list(map(median_of_three, measurement1, measurement2, measurement3, measurement3))
TypeError: median_of_three () accetta 3 argomenti posizionali ma ne sono stati assegnati 4
map
: la mappatura itera finché un iterable non è ancora completamente consumato, ma assumeNone
dai iterables completamente consumati:import operator measurement1 = [100, 111, 99, 97] measurement2 = [102, 117] # Calculate difference between elements list(map(operator.sub, measurement1, measurement2))
TypeError: tipi di operando non supportati per -: 'int' e 'NoneType'
itertools.imap
efuture_builtins.map
: la mappatura si interrompe non appena si interrompe un iterable: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]
La mappatura si interrompe non appena si interrompe un iterable:
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]
Trasposizione con mappa: utilizzo di "Nessuno" come argomento di funzione (solo 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: l'oggetto 'NoneType' non è richiamabile
Ma c'è una soluzione alternativa per ottenere risultati simili:
def conv_to_list(*args):
return list(args)
list(map(conv_to_list, *image))
# Out: [[1, 4, 7], [2, 5, 8], [3, 6, 9]]
Serie e mappatura parallela
map () è una funzione built-in, il che significa che è disponibile ovunque senza la necessità di utilizzare un'istruzione 'import'. È disponibile ovunque, proprio come print (). Se guardi l'esempio 5, vedrai che ho dovuto usare una dichiarazione di importazione prima di poter usare la stampa carina (import pprint). Quindi pprint non è una funzione incorporata
Mappatura delle serie
In questo caso, ogni argomento dell'iterazione viene fornito come argomento della funzione di mappatura in ordine ascendente. Ciò si verifica quando abbiamo un solo iterabile da mappare e la funzione di mappatura richiede un singolo argomento.
Esempio 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
risultati in
['fly is an insect', 'ant is an insect', 'beetle is an insect', 'cankerworm is an insect']
Esempio 2
print(list(map(len, insects))) # the len function is executed each item in the insect list
risultati in
[3, 3, 6, 10]
Mappatura parallela
In questo caso ogni argomento della funzione di mappatura viene estratto da tutti i iterabili (uno da ciascun iterabile) in parallelo. Pertanto il numero di iterabili forniti deve corrispondere al numero di argomenti richiesti dalla funzione.
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)
Esempio 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)))
risultati in
TypeError: len() takes exactly one argument (4 given)
Esempio 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)))
risultati in
TypeError: animals() missing 3 required positional arguments: 'x', 'y', and 'z'
Esempio 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)))
risultati 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']