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.

366
demandé sur vaultah 2009-08-20 04:27:26

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)
566
répondu Triptych 2009-08-20 00:42:10

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.

80
répondu Mark Rushakoff 2009-08-20 00:36:32

nouveau et soigné en Python 3.5:

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

merci à généralisations supplémentaires de déballage

58
répondu Israel Unterman 2016-08-01 15:18:41
La fonction

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
18
répondu Boris Gorelik 2018-05-25 18:01:34

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]]
11
répondu Andrew Keeton 2009-08-20 00:28:44

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 ).

3
répondu ShadowRanger 2017-11-08 04:52:46
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.

0
répondu Invader 2017-11-07 09:04:30

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]
0
répondu Harry_pb 2018-06-15 16:35:30