Obtention d'une carte() pour retourner une liste en Python 3.x
j'essaie de mapper une liste dans hex, puis d'utiliser la liste ailleurs. En python 2.6, c'était facile:
: Python 2.6:
>>> map(chr, [66, 53, 0, 94])
['B', '5', 'x00', '^']
cependant, sur Python 3.1, ce qui précède renvoie un objet map.
B: Python 3.1:
>>> map(chr, [66, 53, 0, 94])
<map object at 0x00AF5570>
Comment puis-je récupérer la liste mappée (comme dans A ci-dessus) sur Python 3.x?
alternativement, y a-t-il une meilleure façon de faire cela? Ma liste initiale objet a environ 45 articles et id comme pour les convertir en hex.
8 réponses
Faites ceci:
list(map(chr,[66,53,0,94]))
en Python 3+, de nombreux processus itératifs sur itérables renvoient des itérateurs eux-mêmes. Dans la plupart des cas, cela finit par sauver la mémoire, et devrait faire les choses aller plus vite.
si tout ce que vous allez faire est itérer sur cette liste éventuellement, il n'y a pas besoin de le convertir même en une liste, parce que vous pouvez toujours itérer sur le map
objet comme cela:
# Prints "ABCD"
for ch in map(chr,[65,66,67,68]):
print(ch)
Pourquoi n'êtes-vous pas faire:
[chr(x) for x in [66,53,0,94]]
ça s'appelle une compréhension de liste. Vous pouvez trouver de nombreuses informations sur Google, mais voici le lien vers la documentation Python (2.6) sur la liste des compréhensions . Vous pourriez être plus intéressé par la documentation Python 3 , cependant.
nouveau et soigné en Python 3.5:
[*map(chr, [66, 53, 0, 94])]
retour de liste-fonction de carte a l'avantage d'économiser la dactylographie, en particulier pendant les sessions interactives. Vous pouvez définir la fonction lmap
(sur l'analogie de imap
de python2 ) qui renvoie la liste:
lmap = lambda func, *iterable: list(map(func, *iterable))
puis appeler lmap
au lieu de map
fera l'affaire:
lmap(str, x)
est plus court de 5 caractères (30% dans ce cas) que list(map(str, x))
et est certainement plus court que [str(v) for v in x]
. Vous pouvez créer des fonctions similaires pour filter
aussi.
il y a eu un commentaire à la question originale:
je suggérerais de renommer getting map() pour retourner une liste en Python 3.* comme il s'applique à toutes les versions de Python3. Est-il un moyen de faire cela? - meawoppl Jan 24 à 17: 58
Il est possible de le faire, mais c'est une très mauvaise idée. Juste pour le plaisir, voici comment vous pouvez ( mais ne devrait pas ):
__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
Je ne suis pas familier avec Python 3.1, mais est-ce que ça va marcher?
[chr(x) for x in [66, 53, 0, 94]]
Conversion mon ancien commentaire pour une meilleure visibilité: Pour une "meilleure façon de le faire" sans map
tout à fait, si votre résultats sont connus pour être ASCII ordinaux, il est généralement beaucoup plus rapide à se convertir au 151920920" et de décoder, à la bytes(list_of_ordinals).decode('ascii')
. Qui vous obtient un str
des valeurs, mais si vous avez besoin d'un list
pour la mutabilité ou, vous pouvez simplement convertir (et c'est encore plus rapide). Par exemple, dans ipython
microbenchmarks conversion 45 entrées:
>>> %%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 vous le laissez comme un str
, il prend ~20% du temps des solutions les plus rapides map
; même en convertissant retour à la liste, il est encore moins de 40% de la solution la plus rapide map
. Convertissez en vrac via bytes
et bytes.decode
puis convertissez en vrac de nouveau en list
sauve beaucoup de travail, mais comme noté, ne fonctionne que si toutes vos entrées sont ASCII ordinals (ou ordinals dans quelque un octet par caractère encodage spécifique à la localité, p.ex. latin-1
).
list(map(chr, [66, 53, 0, 94]))
de la carte(func, *iterables) --> objet map Faire un itérateur qui calcule la fonction en utilisant les arguments de chacun des iterables. S'arrête lorsque le plus court itérable est épuisé.
"Faire un itérateur"
signifie qu'il renvoie un itérateur.
"qui calcule la fonction en utilisant les arguments de chacune des itérables "
signifie que la fonction next() de l'itérateur prendra une valeur de chaque iterables et chacun de passer à un paramètre de position de la fonction.
ainsi vous obtenez un itérateur de la fonction map() et jsut le passer à la fonction list() builtin ou utiliser des compréhensions de liste.
en plus des réponses ci-dessus dans Python 3
, nous pouvons simplement créer un list
des valeurs de résultat d'un map
comme
li = []
for x in map(chr,[66,53,0,94]):
li.append(x)
print (li)
>>>['B', '5', '\x00', '^']
nous pouvons généraliser par un autre exemple où j'ai été frappé, les opérations sur la carte peuvent également être traitées de manière similaire comme dans regex
problème, nous pouvons écrire la fonction pour obtenir list
d'articles à la carte et obtenir ensemble de résultats en même temps. 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]