Pergunta

Eu estou tentando mapear uma lista em hexadecimal, e depois usar a lista em outro lugar. Em Python 2.6, este foi fácil:

A: Python 2.6:

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

No entanto, em Python 3.1, o acima retorna um objeto mapa.

B: Python 3.1:

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

Como faço para recuperar a lista mapeada (como em A acima) em 3.x do Python?

Como alternativa, há uma maneira melhor de fazer isso? Meu objetivo lista inicial tem cerca de 45 itens e eu gostaria de convertê-los em hex.

Foi útil?

Solução

Faça o seguinte:

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

Em Python 3+, muitos processos que iterar sobre iterables retornam iteradores si. Na maioria dos casos, isso acaba salvando memória e deve tornar as coisas mais rápido.

Se tudo o que você vai fazer é iterar sobre esta lista, eventualmente, não há necessidade até mesmo convertê-lo em uma lista, porque você ainda pode interagir sobre o objeto map assim:

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

Outras dicas

Por que você não está fazendo isso:

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

É chamado de uma compreensão da lista. Você pode encontrar muitas informações sobre o Google, mas aqui está o link para o Python (2.6) documentação sobre compreensões lista . Você pode estar mais interessado em o Python 3 documenation , no entanto.

Novo e elegante em Python 3.5:

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

Graças à adicionais Desembalagem Generalizações

Atualizar

Sempre buscando formas mais curtas, descobri este também funciona:

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

Desembalagem trabalha em tuplas também. Observe a vírgula no final. Isso o torna uma tupla de 1 elemento. Ou seja, é equivalente a (*map(chr, [66, 53, 0, 94]),)

É mais curto por apenas um caractere a partir da versão com a lista de menor e maior, mas, na minha opinião, melhor escrever, porque você começa a direita adiante com o asterisco - a sintaxe de expansão, então eu sinto que é mais suave sobre a mente. :)

função de mapa-retornar List tem a vantagem de poupar digitação, especialmente durante sessões interativas. Você pode definir a função lmap (na analogia de imap de python2) que lista os retornos:

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

Em seguida, chamando lmap vez de map irá fazer o trabalho: lmap(str, x) é mais curta por 5 caracteres (30% neste caso) que list(map(str, x)) e é, certamente, mais curto do que [str(v) for v in x]. Você pode criar funções semelhantes para filter também.

Houve um comentário à pergunta inicial:

Gostaria de sugerir uma mudança de nome a começar do mapa () para retornar uma lista em Python 3. * como se aplica a todas as versões python3. Existe uma maneira de fazer isso? - meawoppl 24 de janeiro em 17:58

é possível fazer isso, mas é uma idéia muito ruim. Apenas por diversão, aqui está como você pode (, mas não deve ) fazê-lo:

__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

Eu não estou familiarizado com o Python 3.1, mas este trabalho?

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

meu velho comentar para melhor visibilidade: para uma "melhor maneira de fazer isso" sem map inteiramente, se suas entradas são conhecidos por serem ordinais ASCII, é geralmente muito mais rápido para converter a bytes e decodificar, a la bytes(list_of_ordinals).decode('ascii'). Que você recebe um str dos valores, mas se você precisa de um list para mutabilidade ou similar, você pode simplesmente convertê-lo (e ainda mais rápido é). Por exemplo, em microbenchmarks ipython convertendo 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)

Se você deixá-lo como um str, leva ~ 20% do tempo das soluções mais rápidas map; mesmo converter voltar para a lista ainda é inferior a 40% da solução map mais rápido. Massa convertido via bytes e bytes.decode então granel converter de volta para list poupa muito trabalho, e como se referiu, só funciona se todas as suas entradas são ordinais ASCII (ou ordinais em alguns um byte por localidade específica codificação de caracteres , por exemplo latin-1).

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

mapa (func, iterables *) -> objeto do mapa Faça um iterador que calcula a função usando argumentos de cada um dos iterables. Pára quando o menor iterable está esgotado.

"Faça um iterador"

meios ele irá retornar um iterador.

"que calcula a função usando argumentos de cada um dos iterables"

significa que a função next () do iterador levará um valor de cada iterables e passam cada um deles a um parâmetro posicional da função.

Para que você obtenha um iterador do funtion do mapa () e jsut passá-lo para a lista () builtin função, lista utilização compreensões.

Além de respostas acima em Python 3, podemos simplesmente criar um list de valores resultam de um map como

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

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

Podemos generalizar por um outro exemplo em que fui atingido, as operações no mapa também pode ser tratada de forma semelhante como no problema regex, podemos escrever a função para obter list de itens para mapear e obter conjunto de resultados ao mesmo tempo. 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 compreensão de lista em python e utilidade básica função de mapa, pode-se fazer isso também:

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

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top