2012-06-11 19 views
185
map(function, iterable, ...) 

Aplicar la función a cada elemento de iterable y devolver una lista de los resultados. Si se pasan argumentos iterables adicionales, la función debe tomar tantos argumentos y se aplica a los elementos de todos los iterables en paralelo.Comprender la función de mapa

Si un iterable es más corto que otro, se supone que se extiende con ninguno.

Si la función es None, se asume la función de identidad; si hay múltiples argumentos, map() devuelve una lista que consta de tuplas que contienen los elementos correspondientes de todos los iterables (un tipo de operación de transposición).

Los argumentos iterables pueden ser una secuencia o cualquier objeto iterable; el resultado es siempre una lista.

¿Qué papel juega esto en la fabricación de un producto cartesiano?

content = map(tuple, array) 

¿Qué efecto tiene poner una tupla allí? También noté que sin la función de mapa, la salida es abc y con ella, es a, b, c.

Quiero entender completamente esta función. Las definiciones de referencia también son difíciles de entender. Demasiada pelusa de lujo.

+1

¿Qué es lo que realmente quiere lograr y por qué específicamente desea utilizar 'map'? –

+0

entonces, ¿el mapa simplemente aplica algo a cada elemento? –

+3

@WebMaster sí, según la primera oración en la documentación que pegó - "Aplicar función a cada elemento de iterable". El resto del párrafo trata sobre casos más complejos, como 'map (None, a, b, c)' resulta ser 'zip (a, b, c)'. Pero rara vez se ve eso en la práctica, precisamente porque la llamada 'zip' es equivalente. – lvc

Respuesta

271

map no es particularmente pitónico. Yo recomendaría el uso de listas por comprensión en su lugar:

map(f, iterable) 

es básicamente equivalente a:

[f(x) for x in iterable] 

map por sí solo no puede hacer un producto cartesiano, debido a que la longitud de su lista de salida es siempre el mismo como su lista de entrada. Se puede hacer trivialmente un producto cartesiano con una lista por comprensión sin embargo:

[(a, b) for a in iterable_a for b in iterable_b] 

La sintaxis es un poco confuso - que es básicamente equivalente a:

result = [] 
for a in iterable_a: 
    for b in iterable_b: 
     result.append((a, b)) 
+5

Me parece que el uso de 'map' es mucho menos detallado que las listas de comprensión, al menos para el caso que está demostrando. – marbel

+1

¿Cómo uso el mapa para las propiedades? ¿Cuál es el 'mapa'-equivalente de '[v .__ nombre__ para v en (objeto, str)]'? –

+0

@ASz ¿Qué tal 'map (lambda v: v .__ name__, list)'? –

64

map no se relaciona en absoluto con un producto cartesiano, aunque me imagino que alguien bien versado en programación funcional podría llegar a alguna forma imposible de entender para generar uno usando map.

map en Python 3 es equivalente a esto:

def map(func, iterable): 
    for i in iterable: 
     yield func(i) 

y la única diferencia en Python 2 es que va a construir una lista completa de los resultados de volver todos a la vez en lugar de yield ing.

Aunque convención Python generalmente prefiere comprensión (o expresiones generador) para lograr el mismo resultado que una llamada a map, especialmente si usted está utilizando una expresión lambda como primer argumento:

[func(i) for i in iterable] 

Como ejemplo de lo que solicitó en los comentarios sobre la pregunta: "convertir una cadena en una matriz", en "matriz" probablemente desee una tupla o una lista (ambas se parecen un poco a las matrices de otros idiomas) -

>>> a = "hello, world" 
>>> list(a) 
['h', 'e', 'l', 'l', 'o', ',', ' ', 'w', 'o', 'r', 'l', 'd'] 
>>> tuple(a) 
('h', 'e', 'l', 'l', 'o', ',', ' ', 'w', 'o', 'r', 'l', 'd') 

Un uso de map aquí sería si se comienza con una lista de cadenas en lugar de una sola cadena - map puede listify todos ellos de forma individual:

>>> a = ["foo", "bar", "baz"] 
>>> list(map(list, a)) 
[['f', 'o', 'o'], ['b', 'a', 'r'], ['b', 'a', 'z']] 

Tenga en cuenta que map(list, a) es equivalente en Python 2, pero en Python 3 necesita la llamada list si desea hacer otra cosa que no sea alimentarlo en un bucle for (o una función de procesamiento como sum que solo necesita un iterable, y no una secuencia).Sino también en cuenta una vez más que una lista por comprensión es generalmente preferido:

>>> [list(b) for b in a] 
[['f', 'o', 'o'], ['b', 'a', 'r'], ['b', 'a', 'z']] 
+0

mapa (diversión x -> (x, x)) no parece difícil de entender ... (aunque sería imposible obtener un producto cartesiano verdadero fuera del mapa, cualquier cosa que el mapa produzca sea siempre alguna forma de lista) –

22

map crea una nueva lista aplicando una función a cada elemento de la fuente:

xs = [1, 2, 3] 

# all of those are equivalent — the output is [2, 4, 6] 
# 1. map 
ys = map(lambda x: x * 2, xs) 
# 2. list comprehension 
ys = [x * 2 for x in xs] 
# 3. explicit loop 
ys = [] 
for x in xs: 
    ys.append(x * 2) 

n-aria map es equivalente a comprimir ingrese iterables juntos y luego aplique la función de transformación en cada elemento de esa lista intermedia comprimida. Es no un producto cartesiano:

xs = [1, 2, 3] 
ys = [2, 4, 6] 

def f(x, y): 
    return (x * 2, y // 2) 

# output: [(2, 1), (4, 2), (6, 3)] 
# 1. map 
zs = map(f, xs, ys) 
# 2. list comp 
zs = [f(x, y) for x, y in zip(xs, ys)] 
# 3. explicit loop 
zs = [] 
for x, y in zip(xs, ys): 
    zs.append(f(x, y)) 

He usado zip aquí, pero en realidad map comportamiento difiere ligeramente cuando iterables no son del mismo tamaño - como se ha señalado en su documentación, que se extiende iterables para contener None.

+0

complicado , tratando de digerir esta publicación –

+1

@WebMaster ¿Qué tiene de complicado? –

+0

La mejor respuesta en mi opinión. Usar el lambda en el ejemplo como una función lo deja muy claro. – sheldonzy

17

Simplificando un poco, se puede imaginar map() hacer algo de esta manera:

def mymap(func, lst): 
    result = [] 
    for e in lst: 
     result.append(func(e)) 
    return result 

como se puede ver, se necesita una función y una lista y devuelve una nueva lista con el resultado de aplicar la función de cada uno de los elementos en la lista de entrada. Le dije: "simplificando un poco" porque en realidad map() puede procesar más de un iterable:

Si se pasan argumentos iterables adicionales, la función debe tomar que muchos argumentos y se aplica a los artículos de todas las iterables en paralelo . Si un iterable es más corto que otro, se supone que se extiende con ninguno.

Para la segunda parte de la pregunta: ¿Qué papel juega esto en la fabricación de un producto cartesiano? así, map() podría usarse para generar el producto cartesiano de una lista como esta:

lst = [1, 2, 3, 4, 5] 

from operator import add 
reduce(add, map(lambda i: map(lambda j: (i, j), lst), lst)) 

...Pero, a decir verdad, usando product() es una manera mucho más simple y natural para solucionar el problema:

from itertools import product 
list(product(lst, lst)) 

De cualquier manera, el resultado es el producto cartesiano de lst como se definió anteriormente:

[(1, 1), (1, 2), (1, 3), (1, 4), (1, 5), 
(2, 1), (2, 2), (2, 3), (2, 4), (2, 5), 
(3, 1), (3, 2), (3, 3), (3, 4), (3, 5), 
(4, 1), (4, 2), (4, 3), (4, 4), (4, 5), 
(5, 1), (5, 2), (5, 3), (5, 4), (5, 5)] 
6

Esperanza esto ayuda a alguien que es nuevo en la programación y Python:

la función map() está ahí para aplicar el mismo procedimiento para cada item en un iterable data structure, como lists, generators, strings, y otras cosas.

Veamos un ejemplo: map() puede iterate sobre cada item en un list y aplicar una function a cada item, de lo que se return (a devolver) el new list.

Creo que tiene un function que toma un número (integer), agrega 1 a ese número y lo devuelve.

def add_one(num): 
    new_num = num + 1 
    return new_num 

También tiene un list de números (integers)

my_list = [1,3,6,7,8,10] 

si quieres increment cada número (integer) en el list, puede hacer lo siguiente:

map(add_one, my_list) 

Nota: Como mínimo map() necesita dos arguments. Primero, un nombre function y algo parecido a un list.

resultado del ejemplo anterior, map() le va a devolver esto:

[2, 4, 7, 8, 9, 11] 

vamos a ver algunas otras cosas interesantes map() puede hacer. map() puede tomar iterables múltiple (lists, strings, etc) y aprobar un element de cada list (estoy lista como un ejemplo de uso) a una function como argument.

Hemos siguientes listas:

list_one = [1, 2, 3, 4, 5] 
list_two = [11, 12, 13, 14, 15] 
list_three = [21, 22, 23, 24, 25] 

map() puede hacer que un new list que mantiene la adición de elementos a una (posición) index específica.

Ahora recuerde map(), necesita un function.

def add_from_three_lists(num1, num2, num3): 
    total_num = num1 + num2 + num3 
    return total_num 

ahora permite el uso map() función

map(add_from_three_lists, list_one, List_two, list_three) 

y obtendrá:

[33, 36, 39, 42, 45] 

RECUERDE:
En python2 map(), se iterate (ir a través de los elementos de la lists) accordi ng al más largo list, y pase NoneType a la función para el lists más corto, por lo que su function debe buscar y manejarlos, de lo contrario obtendrá errors. En python 3 map() solo irá de acuerdo con el list más corto. Además, en Python 3, map() devuelve un iterador, no una lista.