Estou tentando mapear uma lista em hexadecimal e depois usá-la em outro lugar. No python 2.6, isso foi fácil:
A: Python 2.6:
>>> map(chr, [66, 53, 0, 94])
['B', '5', '\x00', '^']
No entanto, no Python 3.1, o exemplo acima retorna um objeto de mapa.
B: Python 3.1:
>>> map(chr, [66, 53, 0, 94])
<map object at 0x00AF5570>
Como recupero a lista mapeada (como em A acima) no Python 3.x?
Como alternativa, existe uma maneira melhor de fazer isso? Meu objeto de lista inicial tem cerca de 45 itens e gostaria de convertê-los em hexadecimal.
python
list
python-3.x
map-function
mozami
fonte
fonte
map()
foi quase removido do idioma porque não há motivo para usá-lo em uma compreensão de lista ou em umfor
loop.Respostas:
Faça isso:
No Python 3+, muitos processos que iteram sobre iterables retornam os próprios iteradores. Na maioria dos casos, isso acaba economizando memória e deve acelerar as coisas.
Se tudo o que você fizer é percorrer esta lista eventualmente, não será necessário convertê-la em uma lista, porque você ainda pode percorrer o
map
objeto da seguinte maneira:fonte
map
seria uma avaliação lenta ao iterar em uma função complexa, grandes conjuntos de dados ou fluxos.bytes(sequence_of_ints_in_range_0_to_256).decode('latin-1')
que tornastr
mais rápido, evitando chamadas de função Python para cada elemento em favor de uma conversão em massa de todos os elementos usando apenas chamadas de função no nível C. Você pode incluir o que foi dito acimalist
se realmente precisar de umlist
dos personagens individuais, mas comostr
já é iterável por seus próprios personagens, a única razão pela qual você faria isso é se precisar de mutabilidade.Novo e arrumado no Python 3.5:
Graças a generalizações adicionais de desempacotamento
ATUALIZAR
Sempre procurando caminhos mais curtos, descobri que este também funciona:
A descompactação também funciona em tuplas. 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 em apenas um caractere da versão com os colchetes da lista, mas, na minha opinião, é melhor escrever, porque você começa com o asterisco - a sintaxe de expansão, então acho que é mais suave. :)
fonte
list()
não parece tão purolist
construtor e invocar o mecanismo de chamada de função geral. Para uma entrada longa, não importa; para um curto, pode fazer uma grande diferença. Usando o código acima com a entrada como umatuple
forma que não seja reconstruída repetidamente, asipython
marcas de microparque mostram que alist()
abordagem de empacotamento leva cerca de 20% mais tempo que a descompactação. Lembre-se, em termos absolutos, estamos falando de 150 ns, o que é trivial, mas você entendeu.map
? Talvez com um novo nome (lmap
?), Se o novo padrão é retornar um iterador?*map()
dá erro de sintaxe emPython 3.6
:can't use starred expression here
. Você precisa colocá-lo em umlist
:[ *map() ]
Por que você não está fazendo isso:
Isso se chama compreensão de lista. Você pode encontrar muitas informações no Google, mas aqui está o link para a documentação do Python (2.6) sobre compreensão de lista . Você pode estar mais interessado na documentação do Python 3 .
fonte
map(chr, [66,53,0,94])
é definitivamente mais conciso do que[chr(x) for x in [66,53,0,94]]
.A função de mapa de retorno de lista tem a vantagem de salvar a digitação, especialmente durante as sessões interativas. Você pode definir a
lmap
função (na analogia do python2imap
) que retorna a lista:A chamada, em
lmap
vez demap
, fará o trabalho:lmap(str, x)
é menor em 5 caracteres (30% nesse caso)list(map(str, x))
e certamente menor que[str(v) for v in x]
. Você também pode criar funções semelhantesfilter
.Houve um comentário à pergunta original:
Ele é possível fazer isso, mas é uma idéia muito ruim. Apenas por diversão, veja como você pode ( mas não deve ) fazê-lo:
fonte
Convertendo meu comentário antigo para melhor visibilidade: para uma "melhor maneira de fazer isso" sem
map
inteiramente, se suas entradas são conhecidas como ordinais ASCII, geralmente é muito mais rápido converterbytes
e decodificar a labytes(list_of_ordinals).decode('ascii')
. Isso dá a você umstr
dos valores, mas se você precisar de umlist
para mutabilidade ou algo semelhante, basta convertê-lo (e ainda é mais rápido). Por exemplo, emipython
marcas de micropontos convertendo 45 entradas:Se você deixar como
str
, leva aproximadamente 20% do tempo dasmap
soluções mais rápidas ; mesmo convertendo de volta à lista, ainda é menos de 40% damap
solução mais rápida . A conversão em massa viabytes
e, embytes.decode
seguida, a conversão em massa de volta paralist
economizar muito trabalho, mas , como observado, só funciona se todas as suas entradas forem ordinais ASCII (ou ordinais em algum byte por codificação específica de local do caractere, por exemplolatin-1
).fonte
significa que ele retornará um iterador.
significa que a próxima função () do iterador pegará um valor de cada iterável e passará cada um deles para um parâmetro posicional da função.
Então você obtém um iterador da função map () e passa-o para a função incorporada list () ou usa a compreensão da lista.
fonte
Além das respostas acima
Python 3
, podemos simplesmente criar umlist
dos valores de resultado de amap
asPodemos generalizar por outro exemplo em que fui atingido; as operações no mapa também podem ser tratadas de maneira semelhante, como no
regex
problema; podemos escrever funções para obterlist
itens para mapear e obter resultados ao mesmo tempo. Ex.fonte
Você pode tentar obter uma lista do objeto de mapa apenas iterando cada item no objeto e armazená-lo em uma variável diferente.
fonte
Usando a compreensão de lista no python e no utilitário básico de função de mapa, também é possível fazer isso:
chi = [x for x in map(chr,[66,53,0,94])]
fonte