Buscar..


Sintaxis

  • mapa (función, iterable [, * additional_iterables])
  • future_builtins.map (función, iterable [, * additional_iterables])
  • itertools.imap (función, iterable [, * additional_iterables])

Parámetros

Parámetro Detalles
función función de mapeo (debe tomar tantos parámetros como haya iterables) ( solo de posición )
iterable la función se aplica a cada elemento de lo iterable ( solo posicional )
* adicional_iterables vea iterable, pero tantos como desee ( opcional , solo posicional )

Observaciones

Todo lo que se puede hacer con el map también se puede hacer con comprehensions :

list(map(abs, [-1,-2,-3]))    # [1, 2, 3]
[abs(i) for i in [-1,-2,-3]]  # [1, 2, 3]

Aunque necesitarías zip si tienes múltiples 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]

Las comprensiones de listas son eficientes y pueden ser más rápidas que el map en muchos casos, así que pruebe los tiempos de ambos enfoques si la velocidad es importante para usted.

Uso básico de map, itertools.imap y future_builtins.map

La función de mapa es la más simple entre las incorporaciones de Python utilizadas para la programación funcional. map() aplica una función específica a cada elemento en un iterable:

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>

Se incluye un map compatible con Python 3 en el módulo 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>

Alternativamente, en Python 2 se puede usar imap de itertools para obtener un generador

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>

El resultado se puede convertir explícitamente en una list para eliminar las diferencias entre Python 2 y 3:

list(map(len, names))
# Out: [4, 5, 6]

map() puede reemplazarse por una lista equivalente de comprensión o expresión de generador :

[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>

Mapeando cada valor en una iterable

Por ejemplo, puedes tomar el valor absoluto de cada 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]

Función anónima también soporte para mapear una lista:

map(lambda x:x*2, [1, 2, 3, 4, 5])
# Out: [2, 4, 6, 8, 10]

o convirtiendo valores decimales a porcentajes:

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 convertir dólares a euros (dado un tipo de 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 es una forma conveniente de corregir los parámetros de las funciones para que puedan usarse con map lugar de usar lambda o crear funciones personalizadas.

Mapeo de valores de diferentes iterables.

Por ejemplo, calculando el promedio de cada elemento i -ésimo de múltiples 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]

Hay diferentes requisitos si se pasa más de un iterable al map dependiendo de la versión de python:

  • La función debe tener tantos parámetros como sean 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 () falta 1 argumento posicional requerido: 'c'

    list(map(median_of_three, measurement1, measurement2, measurement3, measurement3))
    

    TypeError: median_of_three () toma 3 argumentos posicionales pero se dieron 4

Python 2.x 2.0.1
  • map : el mapeo se repite siempre y cuando un iterable aún no esté completamente consumido, pero no asuma None de los iterables totalmente consumidos:

    import operator
    
    measurement1 = [100, 111, 99, 97]
    measurement2 = [102, 117]
    
    # Calculate difference between elements
    list(map(operator.sub, measurement1, measurement2))
    

    TypeError: tipo (s) de operando no compatibles para -: 'int' y 'NoneType'

  • itertools.imap y future_builtins.map : la asignación se detiene tan pronto como se detiene una 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 asignación se detiene tan pronto como se detiene una 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]
    

Transposición con mapa: uso de "Ninguno" como argumento de función (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: el objeto 'NoneType' no se puede llamar

Pero hay una solución para tener resultados similares:

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 y mapeo paralelo

map () es una función incorporada, lo que significa que está disponible en todas partes sin la necesidad de usar una declaración de 'importación'. Está disponible en todas partes, como print () Si observa el Ejemplo 5, verá que tuve que usar una declaración de importación antes de que pudiera usar una impresión bonita (pprint de importación). Así pprint no es una función incorporada

Mapeo en serie

En este caso, cada argumento de lo iterable se suministra como argumento a la función de mapeo en orden ascendente. Esto surge cuando solo tenemos un iterable para mapear y la función de mapeo requiere un solo argumento.

Ejemplo 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

resultados en

['fly is an insect', 'ant is an insect', 'beetle is an insect', 'cankerworm is an insect']

Ejemplo 2

print(list(map(len, insects))) # the len function is executed each item in the insect list

resultados en

[3, 3, 6, 10]

Mapeo paralelo

En este caso, cada argumento de la función de mapeo se extrae de todos los iterables (uno de cada iterable) en paralelo. Por lo tanto, el número de iterables suministrados debe coincidir con el número de argumentos requeridos por la función.

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)

Ejemplo 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)))

resultados en

TypeError: len() takes exactly one argument (4 given)

Ejemplo 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)))

resultados en

TypeError: animals() missing 3 required positional arguments: 'x', 'y', and 'z'

Ejemplo 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)))

resultados en

 ['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
Licenciado bajo CC BY-SA 3.0
No afiliado a Stack Overflow