639 votes

Obtenir un map() pour retourner une liste en Python 3.x

J'essaie de convertir une liste en hexagone, puis d'utiliser cette liste ailleurs. Dans python 2.6, c'était facile :

A : Python 2.6 :

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

Cependant, dans Python 3.1, la méthode ci-dessus 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 ?

Sinon, existe-t-il une meilleure façon de procéder ? Mon objet liste initial comporte environ 45 éléments et je voudrais les convertir en hexagones.

16 votes

Il est plus pythique d'utiliser un fichier compréhension de la liste . map() était presque retiré de la langue parce qu'il n'y a aucune raison de l'utiliser au lieu d'une compréhension de liste ou d'une for boucle.

7voto

ShadowRanger Points 44

Convertir mon ancien commentaire pour une meilleure visibilité : Pour une "meilleure façon de faire" sans map entièrement, si vos entrées sont connues pour être des ordinaux ASCII, il est généralement beaucoup plus rapide de convertir en bytes et décoder, à la bytes(list_of_ordinals).decode('ascii') . Cela vous donne un str des valeurs, mais si vous avez besoin d'un list pour la mutabilité ou autre, vous pouvez simplement le convertir (et c'est toujours plus rapide). Par exemple, dans ipython microbenchmarks convertissant 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 en tant que str il prend ~20% du temps du plus rapide. map Même en convertissant en liste, cela représente toujours moins de 40 % des solutions les plus rapides. map solution. Conversion en masse via bytes et bytes.decode puis conversion en vrac pour revenir à list permet d'économiser beaucoup de travail, mais comme indiqué, ne fonctionne que si toutes vos entrées sont des ordinaux ASCII (ou des ordinaux dans un codage spécifique à une locale d'un octet par caractère, par ex. latin-1 ).

3voto

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

map(func, *iterables) --> objet map Crée un itérateur qui calcule la fonction en utilisant les arguments de chacun des itérables. S'arrête lorsque l'itérable le plus court est épuisé.

"Faire un itérateur"

signifie qu'il retournera un itérateur.

"qui calcule la fonction en utilisant les arguments de chacun des itérables"

signifie que la fonction next() de l'itérateur prendra une valeur de chaque itérable et la passera à un paramètre positionnel de la fonction.

Vous obtenez donc un itérateur à partir de la fonction map() et vous le passez à la fonction intégrée list() ou vous utilisez des compréhensions de liste.

1voto

darshan k s Points 15

En utilisant la compréhension de liste en python et l'utilitaire de base de la fonction map, on peut aussi le faire :

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

0 votes

La liste chi contiendra, la valeur ASIC des éléments donnés.

0 votes

Pourquoi la redondance [x for x in map(chr, ...)] alors que vous pourriez simplement utiliser [chr(x) for x in ...] ? Partout où vous utilisez [target for target in iterable] il suffit d'utiliser list(iterable) Dans ce cas, il est inutile d'utiliser une compréhension de liste.

1voto

Anton K Points 761

Une autre option consiste à créer un raccourci, en renvoyant une liste :

from functools import reduce
_compose = lambda f, g: lambda *args: f(g(*args))
lmap = reduce(_compose, (list, map))

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

0voto

Harry_pb Points 1555

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 aussi être traitées de manière similaire comme dans regex on peut écrire la fonction pour obtenir list d'éléments à mettre en correspondance et obtenir un 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 votes

@miradulo Je suppose que dans Python 2, une liste était retournée, mais dans Python 3, seul le type est retourné et j'ai juste essayé de donner dans le même format. Si vous pensez que c'est inutile, il y a peut-être des gens comme moi qui peuvent le trouver utile et c'est pourquoi je l'ai ajouté.

5 votes

Quand il y a déjà une compréhension de liste, une fonction de liste, et une réponse de déballage, une boucle for explicite n'ajoute pas grand chose IMHO.

1 votes

@miradulo cette réponse devrait être simplement downvoted. Un autre commentaire sous une réponse idiote n'apporte pas grand chose.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X