Pregunta

Estoy intentando asignar una lista en hexadecimal y luego usar la lista en otro lugar.En Python 2.6, esto era fácil:

A: Pitón 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: Pitón 3.1:

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

¿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 gustaría convertirlos a hexadecimal.

¿Fue útil?

Solución

Haga lo siguiente:

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

En Python 3+, muchos procesos que iterar sobre iterables vuelven iteradores mismos. En la mayoría de los casos, esto termina salvando la memoria, y debe hacer que las cosas van más rápido.

Si todo lo que vamos a hacer es iterar sobre esta lista con el tiempo, no hay necesidad de convertir incluso a una lista, porque todavía puede iterar sobre el objeto map este modo:

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

Otros consejos

¿Por qué no haces esto?

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

Se llama lista de comprensión.Puedes encontrar mucha información en Google, pero aquí está el enlace a la documentación de Python (2.6) sobre listas por comprensión.Quizás te interese más la documentación de Python 3, aunque.

Nuevo y ordenada en Python 3.5:

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

Gracias a adicional desembalaje generalizaciones

Actualizar

Siempre en la búsqueda de formas más cortas, descubrí éste también funciona:

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

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

Es más corto por un solo carbón de la versión con la lista de soportes en, pero, en mi opinión, mejor escribir, debido a que inicie la derecha por delante con el asterisco - la sintaxis de expansión, por lo que siento que es más suave en la mente. :)

Función de asignación Lista de-volver tiene la ventaja de ahorrar mecanografía, especialmente durante las sesiones interactivas. Se puede definir la función lmap (en la analogía de imap de python2) que devuelve la lista:

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

A continuación, llamando lmap en lugar de map hará el trabajo: lmap(str, x) es más corto por 5 caracteres (30% en este caso) que list(map(str, x)) y es sin duda más corto que [str(v) for v in x]. Es posible crear funciones similares para filter también.

Hubo un comentario a la pregunta original:

  

Yo sugeriría un cambio de nombre para la Obtención del mapa () para devolver una lista en Python 3. * que se aplica a todas las versiones python3. ¿Hay alguna forma de hacer esto? - meawoppl 24 de enero a las 17:58

es posible hacer eso, pero es una idea muy mala. Sólo por diversión, aquí es cómo es posible que ( pero no debe ) 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

No estoy familiarizado con Python 3.1, pero es que esto funciona?

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

mi viejo comentar para una mejor visibilidad: para una "mejor manera de hacer esto" sin map completo, si se conocen sus entradas para ser ordinales ASCII, por lo general es mucho más rápido para convertir a bytes y decodificar, a la bytes(list_of_ordinals).decode('ascii'). Que consigue un str de los valores, pero si usted necesita un list para la mutabilidad o similares, sólo puede convertirlo (y es todavía más rápido). Por ejemplo, en microbenchmarks ipython conversión de 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, se necesita ~ 20% del tiempo de las soluciones más rápidas map; incluso convertir volver a la lista que sigue siendo inferior al 40% de la solución map más rápido. convertir a granel a través de bytes y bytes.decode luego a granel convertir de nuevo a list ahorra mucho trabajo, y como se ha señalado, sólo funciona si todas las entradas son ordinales ASCII (o ordinales en algunos un byte por carácter local codificación específica , por ejemplo latin-1).

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

mapa (Func, iterables *) -> objeto de mapa      Hacer un iterador que calcula la función usando los 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 los argumentos de cada uno de los iterables"

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

Para que pueda obtener un iterador de la funcion del mapa () y jsut lo pasa a la lista () de función incorporada o lista por comprensión uso.

Además de las respuestas anteriores en Python 3, podemos simplemente crear un list de valores de los resultados de una 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 en el que me llamó la atención, las operaciones en el mapa también puede ser manejado de manera similar como en el problema regex, podemos escribir la función de obtener list de artículos 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]

Uso de lista por comprensión en Python y utilidad básica función de mapa, se puede hacer esto también:

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

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top