Getting a map () para devolver una lista en Python 3.x


Estoy tratando de mapear una lista en hexadecimal, y luego usar la lista en otro lugar. En python 2.6, esto fue fácil:

A: Python 2.6:

>>> map(chr, [66, 53, 0, 94])
['B', '5', '\x00', '^']

Sin embargo, en Python 3.1, lo anterior devuelve un objeto map.

B: Python 3.1:

>>> map(chr, [66, 53, 0, 94])
<map object at 0x00AF5570>

Cómo puedo recuperar la lista mapeada (como en A arriba) en Python 3.x?

Alternativamente, ¿hay una mejor manera de hacer esto? Mi objeto de lista inicial tiene alrededor de 45 elementos y id como para convertirlos a hexadecimal.

Author: vaultah, 2009-08-20

8 answers

Haz esto:

list(map(chr,[66,53,0,94]))

En Python 3+, muchos procesos que iteran sobre iterables devuelven iteradores ellos mismos. En la mayoría de los casos, esto termina ahorrando memoria, y debería hacer que las cosas vayan más rápido.

Si todo lo que vas a hacer es iterar sobre esta lista eventualmente, no hay necesidad de convertirla en una lista, porque aún puedes iterar sobre el objeto map de la siguiente manera:

# Prints "ABCD"
for ch in map(chr,[65,66,67,68]):
    print(ch)
 566
Author: Triptych,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-08-20 00:42:10

¿Por qué no estás haciendo esto:

[chr(x) for x in [66,53,0,94]]

Se llama comprensión de lista. Puedes encontrar mucha información en Google, pero aquí está el enlace a la documentación de Python (2.6) en las comprensiones de listas. Sin embargo, podría estar más interesado en la documentación de Python 3.

 80
Author: Mark Rushakoff,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-08-20 00:36:32

Nuevo y ordenado en Python 3.5:

[*map(chr, [66, 53, 0, 94])]

Gracias a Generalizaciones adicionales de Desembalaje

 58
Author: Israel Unterman,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-08-01 15:18:41

La función de mapa de retorno de lista tiene la ventaja de guardar la escritura, especialmente durante las sesiones interactivas. Puede definir la función lmap (en la analogía de la imap de python2) que devuelve la lista:

lmap = lambda func, *iterable: list(map(func, *iterable))

Entonces llamar a lmap en lugar de map hará el trabajo: lmap(str, x) es más corto en 5 caracteres (30% en este caso) que list(map(str, x)) y es ciertamente más corto que [str(v) for v in x]. También puede crear funciones similares para filter.

Hubo un comentario a la pregunta original:

Sugeriría un cambio de nombre a Getting map() para devolver una lista en Python 3.* como se aplica a todas las versiones de Python3. ¿Hay alguna manera de hacer esto? – meawoppl Jan 24 at 17: 58

Es posible hacer eso, pero es una muy mala idea. Solo por diversión, así es como puedes (pero no debes) hacerlo:

__global_map = map #keep reference to the original map
lmap = lambda func, *iterable: list(__global_map(func, *iterable)) # using "map" here will cause infinite recursion
map = lmap
x = [1, 2, 3]
map(str, x) #test
map = __global_map #restore the original map and don't do that again
map(str, x) #iterator
 18
Author: Boris Gorelik,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-05-25 18:01:34

No estoy familiarizado con Python 3.1, pero ¿funcionará esto?

[chr(x) for x in [66, 53, 0, 94]]
 11
Author: Andrew Keeton,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-08-20 00:28:44

Convirtiendo mi antiguo comentario para una mejor visibilidad: Para una "mejor manera de hacer esto" sin map por completo, si sus entradas son conocidas por ser ordinales ASCII, generalmente es mucho más rápido convertir a bytes y decodificar, a la bytes(list_of_ordinals).decode('ascii'). Eso te da un str de los valores, pero si necesitas un list para mutabilidad o similares, puedes convertirlo (y aún así es más rápido). Por ejemplo, en ipython microbenchmarks convirtiendo 45 entradas:

>>> %%timeit -r5 ordinals = list(range(45))
... list(map(chr, ordinals))
...
3.91 µs ± 60.2 ns per loop (mean ± std. dev. of 5 runs, 100000 loops each)

>>> %%timeit -r5 ordinals = list(range(45))
... [*map(chr, ordinals)]
...
3.84 µs ± 219 ns per loop (mean ± std. dev. of 5 runs, 100000 loops each)

>>> %%timeit -r5 ordinals = list(range(45))
... [*bytes(ordinals).decode('ascii')]
...
1.43 µs ± 49.7 ns per loop (mean ± std. dev. of 5 runs, 1000000 loops each)

>>> %%timeit -r5 ordinals = list(range(45))
... bytes(ordinals).decode('ascii')
...
781 ns ± 15.9 ns per loop (mean ± std. dev. of 5 runs, 1000000 loops each)

Si lo dejas como un str, toma ~20% del tiempo de las soluciones map más rápidas; incluso volviendo a la lista, sigue siendo menos del 40% de la solución map más rápida. Conversión masiva a través de bytes y bytes.decode luego la conversión masiva a list ahorra mucho trabajo, pero como se señaló, solo funciona si todas sus entradas son ordinales ASCII (u ordinales en algún byte por codificación específica de la configuración regional de carácter, por ejemplo, latin-1).

 3
Author: ShadowRanger,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-11-08 04:52:46
list(map(chr, [66, 53, 0, 94]))

Map (func, * iterables) object > map object Hacer un iterador que calcula la función usando argumentos de cada uno de los iterables. Se detiene cuando se agota el iterable más corto.

"Hacer un iterador"

Significa que devolverá un iterador.

"que calcula la función usando argumentos de cada uno de los iterables"

Significa que la función next() del iterador tomará un valor de cada iterable y pasará cada uno de ellos a un parámetro posicional de la función.

Entonces obtienes un iterador de la función map() y jsut lo pasa a la función incorporada list() o usa comprensiones de lista.

 0
Author: Invader,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-11-07 09:04:30

Además de las respuestas anteriores en Python 3, simplemente podemos crear un list de valores de resultado a partir de un map como

li = []
for x in map(chr,[66,53,0,94]):
    li.append(x)

print (li)
>>>['B', '5', '\x00', '^']

Podemos generalizar por otro ejemplo donde me golpearon, las operaciones en el mapa también se pueden manejar de manera similar como en el problema regex, podemos escribir la función para obtener list de elementos para mapear y obtener el conjunto de resultados al mismo tiempo. Ex.

b = 'Strings: 1,072, Another String: 474 '
li = []
for x in map(int,map(int, re.findall('\d+', b))):
    li.append(x)

print (li)
>>>[1, 72, 474]
 0
Author: Harry_pb,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-06-15 16:35:30