for - python mapped
Entendiendo la funciĆ³n del mapa (6)
map(function, iterable, ...)
Aplicar la función a cada elemento de iterable y devolver una lista de los resultados. Si se pasan otros argumentos iterables, la función debe tomar tantos argumentos y se aplica a los elementos de todos los iterables en paralelo.
Si uno de los iterables es más corto que otro, se supone que está extendido con elementos Ninguno.
Si la función es None
, se asume la función de identidad; si hay varios 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 en cualquier lugar? 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. Demasiado pelusa de lujo.
Python3 - mapa (func, iterable)
Una cosa que no se mencionó completamente (aunque @BlooB lo mencionó un poco) es que el mapa devuelve un objeto de mapa NO una lista. Esta es una gran diferencia cuando se trata del tiempo de rendimiento en la inicialización y la iteración. Considere estas dos pruebas.
import time
def test1(iterable):
a = time.clock()
map(str, iterable)
a = time.clock() - a
b = time.clock()
[ str(x) for x in iterable ]
b = time.clock() - b
print(a,b)
def test2(iterable):
a = time.clock()
[ x for x in map(str, iterable)]
a = time.clock() - a
b = time.clock()
[ str(x) for x in iterable ]
b = time.clock() - b
print(a,b)
test1(range(2000000)) # Prints ~1.7e-5s ~8s
test2(range(2000000)) # Prints ~9s ~8s
Como puede ver, la inicialización de la función de mapa lleva casi nada de tiempo. Sin embargo, la iteración a través del objeto de mapa lleva más tiempo que simplemente iterar a través de lo iterable. Esto significa que la función pasada a map () no se aplica a cada elemento hasta que se alcanza el elemento en la iteración. Si quieres una lista usa la lista de comprensión. Si planea recorrer en iteración en un bucle for y se interrumpirá en algún momento, utilice el mapa.
La función map()
está ahí para aplicar el mismo procedimiento a cada elemento en una estructura de datos iterable, como listas, generadores, cadenas y otras cosas.
Veamos un ejemplo: map()
puede iterar sobre cada elemento de una lista y aplicar una función a cada elemento, lo que devolverá (le devolverá) la nueva lista.
Imagina que tienes una función que toma un número, agrega 1 a ese número y lo devuelve:
def add_one(num):
new_num = num + 1
return new_num
También tienes una lista de números:
my_list = [1, 3, 6, 7, 8, 10]
Si desea incrementar cada número en la lista, puede hacer lo siguiente:
>>> map(add_one, my_list)
[2, 4, 7, 8, 9, 11]
Nota: Como mínimo map()
necesita dos argumentos. Primero un nombre de función y segundo algo así como una lista.
Veamos algunas otras cosas geniales que el map()
puede hacer. map()
puede tomar múltiples iterables (listas, cadenas, etc.) y pasar un elemento de cada iterable a una función como un argumento.
Tenemos tres 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 una nueva lista contenga la adición de elementos en un índice específico.
Ahora recuerda map()
, necesita una función. Esta vez usaremos la función sum()
incorporada. El map()
ejecución map()
da el siguiente resultado:
>>> map(sum, list_one, list_two, list_three)
[33, 36, 39, 42, 45]
RECUERDA:
En Python 2 map()
, recorrerá (recorrerá los elementos de las listas) de acuerdo con la lista más larga, y pasará None
a la función para las listas más cortas, por lo que su función debe buscar None
y manejarlas, de lo contrario obtendrá errores En Python 3, el map()
se detendrá después de terminar con la lista más corta. Además, en Python 3, map()
devuelve un iterador, no una lista.
Simplificando un poco, puedes imaginarte a map()
haciendo algo como esto:
def mymap(func, lst):
result = []
for e in lst:
result.append(func(e))
return result
Como puede ver, toma una función y una lista, y devuelve una nueva lista con el resultado de aplicar la función a cada uno de los elementos en la lista de entrada. Dije "simplificar un poco" porque en realidad map()
puede procesar más de una iterable:
Si se pasan otros argumentos iterables, la función debe tomar tantos argumentos y se aplica a los elementos de todos los iterables en paralelo. Si uno de los iterables es más corto que otro, se supone que está extendido con elementos Ninguno.
Para la segunda parte de la pregunta: ¿Qué papel juega esto en la fabricación de un producto cartesiano? bueno, 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 para decir la verdad, usar product()
es una forma mucho más simple y natural de resolver 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)]
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)
El map
n-aria es equivalente a comprimir juntos los iterables de entrada y luego aplicar la función de transformación en cada elemento de esa lista comprimida intermedia. No es 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 el comportamiento del map
realidad difiere ligeramente cuando los iterables no son del mismo tamaño, como se indica en su documentación, extiende los iterables para contener None
.
map
no es particularmente pitónico. Recomendaría usar listas de 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, porque la longitud de su lista de salida es siempre la misma que su lista de entrada. Sin embargo, puede hacer un producto cartesiano de forma trivial con una lista de comprensión:
[(a, b) for a in iterable_a for b in iterable_b]
La sintaxis es un poco confusa, básicamente equivale a:
result = []
for a in iterable_a:
for b in iterable_b:
result.append((a, b))
map
no se relaciona en absoluto con un producto cartesiano, aunque imagino que alguien bien versado en programación funcional podría encontrar una forma imposible de entender de generar un map
usando un 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 construirá una lista completa de resultados para devolverlos todos a la vez en lugar de yield
.
Aunque la convención de Python generalmente prefiere la comprensión de listas (o expresiones generadoras) para lograr el mismo resultado que una llamada a un map
, especialmente si está usando una expresión lambda como primer argumento:
[func(i) for i in iterable]
Como ejemplo de lo que pidió en los comentarios sobre la pregunta: "convertir una cadena en una matriz", por "matriz" es probable que desee una tupla o una lista (ambas se comportan un poco como 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 del map
aquí sería si comienzas con una lista de cadenas en lugar de una sola cadena - el map
puede listarlas todas individualmente:
>>> 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 a la list
si desea hacer algo más que alimentarlo en un bucle for
(o una función de procesamiento como la sum
que solo necesita un iterable). , y no una secuencia). Pero también tenga en cuenta de nuevo que generalmente se prefiere una lista de comprensión:
>>> [list(b) for b in a]
[[''f'', ''o'', ''o''], [''b'', ''a'', ''r''], [''b'', ''a'', ''z'']]