Obtención de un mapa () 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 de mapa.

B: Python 3.1:

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

¿Cómo recupero la lista asignada (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 me gusta convertirlos en hex.

Hacer esto:

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

En Python 3+, muchos procesos que se repiten en iterables devuelven a los iteradores. En la mayoría de los casos, esto termina guardando 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 a una lista, porque aún puedes iterar sobre el objeto del map así:

 # Prints "ABCD" for ch in map(chr,[65,66,67,68]): print(ch) 

¿Por qué no estás haciendo esto?

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

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

Nuevo y limpio en Python 3.5:

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

Gracias a las generalizaciones de desembalaje adicionales

ACTUALIZAR

Siempre buscando formas más cortas, descubrí que esta también funciona:

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

Desembalaje también funciona en tuplas. Tenga en cuenta la coma al final. Esto lo convierte en una tupla de 1 elemento. Es decir, es equivalente a (*map(chr, [66, 53, 0, 94]),)

Es más corto por solo un carácter de la versión con la lista de paréntesis, pero, en mi opinión, es mejor escribir, porque empiezas por delante con el asterisco: la syntax de expansión, así que siento que es más suave para la mente. 🙂

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 del imap de python2) que devuelve la lista:

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

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

Hubo un comentario a la pregunta original:

Yo 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 forma de hacer esto? – meawoppl 24 de enero a las 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 #restre the original map and don't do that again map(str, x) #iterator 

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

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

Convertir mi comentario anterior para una mejor visibilidad: para una “mejor manera de hacer esto” sin map completo, si se sabe que sus entradas son ordinales ASCII, generalmente es mucho más rápido convertir a bytes y decodificar, a la bytes(list_of_ordinals).decode('ascii') . Eso le da una serie de valores, pero si necesita una list de mutabilidad o similar, puede convertirla (y aún es más rápido). Por ejemplo, en ipython ipython que convierten 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 deja como un str , toma ~ 20% del tiempo de las soluciones de map más rápidas; incluso volviendo a la lista es aún menos del 40% de la solución de map más rápida. La conversión masiva a través de bytes y bytes bytes.decode Luego, la conversión masiva a la list ahorra mucho trabajo, pero como se indicó, solo funciona si todas sus entradas son ordinales ASCII (u ordinales en algún byte por encoding de locale de caracteres específicos, por ejemplo latin-1 ).

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

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

“Hacer un iterador”

Significa que devolverá un iterador.

“que calcula la función utilizando 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.

Así que obtienes un iterador de la función map () y simplemente lo pasas a la función incorporada list () o utilizas la lista de comprensión.

Además de las respuestas anteriores en Python 3 , podemos simplemente crear una list de valores de resultados de un map como

 li = [] for x in map(chr,[66,53,0,94]): li.append(x) print (li) >>>['B', '5', '\x00', '^'] 

Podemos generalizar mediante otro ejemplo en el que me golpearon, las operaciones en el mapa también pueden manejarse de manera similar a como se hace en el problema de regex , podemos escribir la función para obtener una 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] 

Usando la comprensión de listas en Python y la utilidad básica de la función de mapa, también se puede hacer esto:

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