Question

Est-ce que la carte () itérer dans la liste comme « pour » le ferait? Y at-il une valeur en utilisant la carte pour vs?

Si oui, en ce moment mon code ressemble à ceci:

for item in items:
    item.my_func()

S'il est logique, je voudrais rendre la carte (). Est-ce possible? Qu'est-ce qu'un exemple comme?

Était-ce utile?

La solution

Vous pouvez utiliser map au lieu de la boucle de for vous » ve montré, mais puisque vous ne semblez pas utiliser le résultat de item.my_func(), ceci est pas recommandé . map doit être utilisé si vous souhaitez appliquer une fonction sans effets secondaires à tous les éléments d'une liste. Dans tous les autres cas, utilisez un explicite pour la boucle.

En outre, à partir de map Python 3.0 retourne un générateur, donc dans ce map cas ne se comportera pas de la même (à moins que vous évaluez explicitement tous les éléments retournés par le générateur, par exemple en appelant list sur elle).


Modifier : kibibu demande dans les commentaires des éclaircissements sur les raisons premier argument de map devrait ne pas être une fonction avec des effets secondaires. Je vais vous donner répondre à cette question un coup de feu:

map est destiné à être passé une fonction f dans le sens mathématique . Dans de telles circonstances, il n'a pas d'importance dans quel ordre f est appliqué aux éléments du second argument (tant qu'ils sont retour dans leur ordre original, bien sûr). Plus important encore, dans ces circonstances map(g, map(f, l)) est sémantiquement équivalent à map(lambda x: g(f(x)), l), quel que soit l'ordre dans lequel f et g sont appliqués à leurs entrées respectives .

par exemple., Peu importe si les retours de map et iterator ou une liste complète à la fois. Cependant, si f et / ou g provoquer des effets secondaires, cette équivalence est garanti que si la sémantique de map(g, map(f, l)) sont telles que, à tout g de phase est appliqué à la première n éléments renvoyés par map(f, l) avant map(f, l) applique f à la (n + 1) st élément de l. (Ce qui signifie que map doit effectuer l'itération possible --- paresseuse ce qu'il fait en Python 3, mais pas en Python 2!)

Franchir une étape supplémentaire: même si l'on suppose la mise en œuvre Python 3 map, l'équivalence sémantique peut facilement tomber en panne si la sortie de map(f, l) est par exemple passé à travers itertools.tee avant d'être fourni à l'appel map externe.

La discussion ci-dessus peut sembler de nature théorique, mais que les programmes deviennent plus complexes, ils deviennent plus difficiles à raisonner sur et donc plus difficile à déboguer. Veiller à ce que certaines choses sont invariantes atténue ce problème un peu, et peut empêcher, en fait, toute une classe de bogues.

Enfin, beaucoup de gens map rappelle de son homologue vraiment fonctionnel dans différentes langues fonctionnelles (purement). En passant une « fonction » avec des effets secondaires confondra ces personnes. Par conséquent, car l'alternative (à savoir, en utilisant une boucle explicite) n'est pas plus difficile à mettre en œuvre qu'un appel à map, il est fortement recommandé que l'on restreint l'utilisation de map à ces cas où la fonction à appliquer ne provoque pas d'effets secondaires .

Autres conseils

Vous pouvez écrire cette carte en utilisant comme ceci:

map(cls.my_func, items)

remplaçant cls avec la classe des articles que vous itérez.

Comme mentionné par Stephan202, ceci est pas recommandé dans ce cas.

En règle générale, si vous voulez créer une nouvelle liste en appliquant une fonction à chaque élément de la liste, utilisez la carte. Cela a l'implicite qui signifie que la fonction n'a aucun effet secondaire, et vous pourriez ainsi (potentiellement) exécuter la carte en parallèle.

Si vous ne voulez pas créer une nouvelle liste, ou si la fonction a des effets secondaires, utiliser une boucle. Tel est le cas dans votre exemple.

Il y a une légère différence sémantique, qui est probablement fermé dans les spécifications du langage Python. carte est explicitement parallélisables, alors que pour uniquement dans des situations particulières. Le code peut casser à partir de pour , mais seulement échapper à l'exception de carte .

A mon avis carte ne devrait pas également garantir l'ordre d'application de fonction alors que pour doit. Autant que je sache aucune implémentation de Python est actuellement en mesure de le faire auto-parallélisation.

Vous pouvez passer votre map à certains frais cadre informatique fileté ou multitraitement distribués ou si vous avez besoin. Disco est un exemple de distribution, aux défaillances cadre fondé sur Erlang et-python. Je configuré sur 2 boîtes de 8 cœurs et maintenant mon programme court 16 fois plus rapide, grâce au cluster Disco, mais je devais réécrire mon programme de compréhensions de liste et pour les boucles de map / reduce.

Il est la même affaire d'écrire un programme en utilisant des boucles et des compréhensions de liste et map / reduce, mais quand vous avez besoin de fonctionner sur un cluster, vous pouvez le faire presque gratuitement si vous utilisez map / reduce. Si vous ne l'avez pas, eh bien, vous devrez réécrire.

Attention: pour autant que je sache, 2.x python retourne une liste au lieu d'un itérateur de carte. J'ai entendu cela peut être contournée en utilisant iter.imap() (jamais utilisé si).

Utilisez un explicite en boucle lorsque vous n'avez pas besoin d'une liste de résultats de retour (par exemple. Fonctions avec des effets secondaires).

Utilisez une compréhension de la liste lorsque vous avez besoin d'une liste de résultats de retour (par exemple. Les fonctions qui renvoient une valeur basée directement sur l'entrée).

Utilisez la carte () lorsque vous essayez de convaincre les utilisateurs Lisp que Python est intéressant d'utiliser. ;)

Le principal avantage de map est quand vous voulez obtenir le résultat d'un calcul sur chaque élément dans une liste. Par exemple, cet extrait double chaque valeur dans une liste:

map(lambda x: x * 2, [1,2,3,4])  #=> [2, 4, 6, 8]

Il est important de noter que map retourne une nouvelle liste des résultats. Il ne modifie pas la liste initiale en place.

Pour faire la même chose avec for, vous devez créer une liste vide et ajouter une ligne supplémentaire au corps de for pour ajouter le résultat de chaque calcul à la nouvelle liste. La version map est plus concis et fonctionnel.

Carte peut parfois être plus rapide pour les fonctions intégrées que le codage manuellement une boucle. Essayez carte de synchronisation (str, plage (1000000)) par rapport à un analogue de la boucle.

map(lambda item: item.my_func(), items)
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top