Domanda

Sto cercando di mappare una lista in esadecimale, e quindi utilizzare l'elenco altrove. In Python 2.6, questo è stato facile:

A: Python 2.6:

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

Tuttavia, in Python 3.1, quanto sopra restituisce un oggetto della mappa.

B: Python 3.1:

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

Come faccio a recuperare la lista mappata (come in A sopra) su Python 3.x?

In alternativa, c'è un modo migliore di fare questo? Il mio scopo elenco iniziale ha circa 45 oggetti e id come per convertirli in esadecimale.

È stato utile?

Soluzione

Fare questo:

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

In Python 3+, molti processi che eseguono iterazioni su iterables restituiscono iteratori stessi. Nella maggior parte dei casi, questo finisce per salvare la memoria, e dovrebbe rendere le cose vanno più veloci.

Se tutto quello che stai andando a fare è iterare questo elenco alla fine, non c'è bisogno di convertire anche a un elenco, perché si può ancora scorrere sopra l'oggetto map in questo modo:

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

Altri suggerimenti

Perché non state facendo questo:

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

Si chiama una lista di comprensione. È possibile trovare un sacco di informazioni su Google, ma ecco il link al Python (2.6) documentazione su list comprehension . Si potrebbe essere più interessati a il Python 3 documenation , però.

Nuovo e pulito in Python 3.5:

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

Grazie alla aggiuntive Apertura della confezione generalizzazioni

Aggiorna

Sempre alla ricerca di modi più brevi, ho scoperto questo funziona anche:

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

Apertura della confezione lavora in tuple troppo. Si noti la virgola alla fine. Questo lo rende una tupla di 1 elemento. Cioè, è equivalente a (*map(chr, [66, 53, 0, 94]),)

E 'più corta di un solo carattere dalla versione con la Lista staffe, ma, a mio parere, meglio scrivere, perché si inizia a destra avanti con l'asterisco - la sintassi di espansione, quindi mi sento che è più morbida sulla mente. :)

funzione mappa List-ritorno ha il vantaggio di risparmio di battitura, soprattutto durante sessioni interattive. È possibile definire la funzione lmap (in analogia imap di python2) che restituisce la lista:

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

Poi chiamando lmap invece di map farà il lavoro: lmap(str, x) è più corta di 5 caratteri (30% in questo caso) di list(map(str, x)) ed è certamente più breve di [str(v) for v in x]. È possibile creare funzioni simili per filter troppo.

C'è stato un commento alla domanda iniziale:

  

Vorrei suggerire una ridenominazione di Getting mappa () per restituire un elenco in Python 3. * in quanto si applica a tutte le versioni python3. C'è un modo per fare questo? - meawoppl 24 gennaio alle 17:58

è possibile farlo, ma è una pessima idea. Solo per divertimento, ecco come si può ( ma non dovrebbe ) farlo:

__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

Non ho dimestichezza con Python 3.1, ma sarà questo lavoro?

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

mio vecchio commento per una migliore visibilità: per un "modo migliore per fare questo" senza map del tutto, se gli ingressi sono noti per essere ordinali ASCII, è generalmente molto più veloce per convertire in bytes e decodificare, alla bytes(list_of_ordinals).decode('ascii'). Che si ottiene un str dei valori, ma se avete bisogno di un list per mutevolezza o simili, si può semplicemente convertirlo (ed è ancora più veloce). Ad esempio, in microbenchmarks ipython conversione 45 ingressi:

>>> %%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 si lascia come un str, ci vuole ~ 20% del tempo delle soluzioni map più veloci; anche convertire torna alla lista è ancora inferiore al 40% della soluzione map più veloce. convert Bulk via bytes e bytes.decode poi alla rinfusa La riconversione list consente di risparmiare un sacco di lavoro, ma come noto, funziona solo se tutti gli ingressi sono ordinali ASCII (o ordinali in alcuni un byte per la codifica specifica localizzazione dei caratteri , ad esempio latin-1).

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

mappa (func, * iterables) -> Mappa oggetto      Crea un iteratore che calcola la funzione usando argomenti da      ciascuno dei iterabili. Si arresta quando l'iterabile più breve è esaurito.

     

"Crea un iteratore"

significa che restituirà un iteratore.

  

"che calcola la funzione utilizzando argomenti da ognuno dei iterables"

significa che la successiva funzione () dell'iteratore avrà un valore di ogni iterables e trasmettere ciascuno di essi di un parametro posizionale della funzione.

Così si ottiene un iteratore dal funtion mappa () e sono finite passa alla lista () o funzione built-list comprehension uso.

Oltre alle risposte di cui sopra in Python 3, possiamo semplicemente creare un list di valori risultanti da una map come

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

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

Si può generalizzare da un altro esempio in cui mi ha colpito, le operazioni sulla carta possono anche essere gestiti in modo simile come nel problema regex, possiamo scrivere la funzione per ottenere list di articoli per la mappa e ottenere set di risultati, allo stesso 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]

Utilizzo di lista in Python e l'utilità mappa funzione di base, si può fare anche questo:

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

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top