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']
Python 3.x 3.0
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 :

Python 2.x 2.6
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

Python 2.x 2.3
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

Python 2.x 2.0.1
  • map : la mappatura itera finché un iterable non è ancora completamente consumato, ma assume None 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 e future_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]
    
Python 3.x 3.0.0
  • 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
Python 3.x 3.0.0
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']


Modified text is an extract of the original Stack Overflow Documentation
Autorizzato sotto CC BY-SA 3.0
Non affiliato con Stack Overflow