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.
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)
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.
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])]
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
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]]
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
).
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.
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]
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