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.

901voto

Triptych Points 70247

Faites-le :

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

Dans Python 3+, de nombreux processus qui itèrent sur des itérables retournent eux-mêmes des itérateurs. Dans la plupart des cas, cela permet d'économiser de la mémoire et d'accélérer les choses.

Si tout ce que vous avez l'intention de faire est d'itérer sur cette liste, il n'est même pas nécessaire de la convertir en liste, car vous pouvez toujours itérer sur le fichier map comme suit :

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

21 votes

Bien sûr, vous pouvez aussi itérer sur cette fonction : (chr(x) for x in [65,66,67,68]). Il n'y a même pas besoin de map.

5 votes

@hughdbrown L'argument en faveur de l'utilisation des 3.1 map serait l'évaluation paresseuse lors de l'itération sur une fonction complexe, de grands ensembles de données ou des flux.

26 votes

@Andrew en fait Hugh utilise un générateur de compréhension qui ferait la même chose. Notez les parenthèses plutôt que les crochets.

174voto

CodeChords man Points 3191

Nouveau et soigné dans Python 3.5 :

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

Merci à Généralisations supplémentaires sur le déballage

UPDATE

Toujours à la recherche de moyens plus courts, j'ai découvert que celui-ci fonctionne également :

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

Le déballage fonctionne aussi pour les tuples. Notez la virgule à la fin. Cela en fait un tuple de 1 élément. C'est-à-dire que c'est équivalent à (*map(chr, [66, 53, 0, 94]),)

Il est plus court d'un seul caractère par rapport à la version avec les parenthèses de liste, mais, à mon avis, il est plus facile à écrire, parce que vous commencez directement avec l'astérisque - la syntaxe d'expansion, donc je pense que c'est plus doux pour l'esprit :).

12 votes

@Quelklef list() n'a pas l'air aussi soigné

7 votes

@Quelklef : De plus, l'approche de déballage est trivialement plus rapide grâce à l'absence de recherche de l'adresse de l'utilisateur. list et invoquer la machinerie générale d'appel de fonction. Pour une entrée longue, cela n'aura pas d'importance ; pour une entrée courte, cela peut faire une grande différence. En utilisant le code ci-dessus avec l'entrée comme un tuple pour qu'il ne soit pas reconstruit à plusieurs reprises, ipython Les microbenchmarks montrent que les list() L'approche d'emballage prend environ 20 % plus de temps que le déballage. Attention, en termes absolus, nous parlons d'environ 150 ns, ce qui est insignifiant, mais vous comprenez l'idée.

0 votes

Quel était le problème avec l'ancienne map ? Peut-être avec un nouveau nom ( lmap ?) si le nouveau défaut est de retourner un itérateur ?

122voto

Mark Rushakoff Points 97350

Pourquoi ne le faites-vous pas ?

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

C'est ce qu'on appelle la compréhension d'une liste. Vous pouvez trouver beaucoup d'informations sur Google, mais voici le lien vers la documentation Python (2.6) sur les compréhensions de listes . Vous pourriez être plus intéressé par la documentation sur Python 3 mais

4 votes

Hmmmm. Peut-être qu'il faudrait faire un post général sur les compréhensions de listes, les générateurs, map(), zip(), et beaucoup d'autres trucs rapides d'itération en python.

51 votes

Je suppose que c'est plus verbeux, que vous devez écrire une variable supplémentaire (deux fois)... Si l'opération est plus complexe et que vous finissez par écrire un lambda, ou que vous avez également besoin de supprimer certains éléments, je pense qu'une compréhension est définitivement meilleure qu'une map+filtre, mais si vous avez déjà la fonction que vous voulez appliquer, map est plus succinct.

1 votes

+1 : Plus facile à lire et permet d'utiliser des fonctions avec de nombreux paramètres.

28voto

bgbg Points 4713

La fonction de carte à retour de liste présente l'avantage d'économiser la saisie, notamment lors de sessions interactives. Vous pouvez définir lmap (par analogie avec la fonction imap ) qui renvoie une liste :

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

Puis appel 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 courte que [str(v) for v in x] . Vous pouvez créer des fonctions similaires pour filter aussi.

Il y avait un commentaire à la question originale :

Je suggérerais un renommage pour obtenir map() pour retourner une liste dans Python 3.* car cela s'applique à toutes les versions de Python3. Existe-t-il un moyen de le faire ? - 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 ) le faire :

__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

11voto

Andrew Keeton Points 6268

Je ne suis pas familier avec Python 3.1, mais cela fonctionnera-t-il ?

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

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