962 votes

Filtrage de liste : compréhension vs lambda + filtre la liste

Il m'est arrivé de me retrouver à avoir une base de filtrage besoin: j'ai une liste et je filtre par un attribut des éléments.

Mon code ressemble à ceci:

my_list = [i for i in my_list if i.attribute == value]

Mais ensuite j'ai pensé, ne serait-il pas mieux de l'écrire comme ça?

filter(lambda x: x.attribute == value, my_list)

C'est plus lisible, et si nécessaire pour la performance de la lambda pourraient être prises pour obtenir quelque chose.

La Question est: existe-il des mises en garde à l'aide de la deuxième? Toute différence de performances? Ai-je raté le Pythonic Façon™ entièrement et devrait le faire dans encore un autre moyen (comme l'utilisation de itemgetter au lieu de la lambda)?

652voto

Duncan Points 25356

Il est étrange de constater combien la beauté varie pour différentes personnes. - Je trouver la liste de compréhension beaucoup plus claire que le laid filtre+lambda, mais d'utiliser celui qui vous est le plus facile. Cependant, ne cesser de donner vos noms de variables déjà utilisées pour les objets internes, c'est juste moche, et pas ouvert à la discussion.

Il y a deux choses qui peuvent ralentir votre utilisation du filtre.

Le premier est l'appel de la fonction généraux: dès que vous utilisez une fonction Python (qu'elle soit créée par def ou lambda), il est probable que le filtre sera plus lente que la compréhension de liste. Il n'est presque certainement pas assez de matière, et vous ne devriez pas penser beaucoup plus au sujet de la performance jusqu'à ce que vous avez chronométré votre code et l'a trouvé pour être un goulot d'étranglement, mais la différence est là.

Les autres frais généraux qui pourraient s'appliquer, c'est que le lambda est contraint d'accéder à une étendue variable (value). Qui est plus lent que l'accès à une variable locale et en Python 2.x la compréhension de liste accède seulement les variables locales. Si vous êtes à l'aide de Python 3.x la compréhension de liste s'exécute dans une fonction distincte de sorte qu'il sera également accéder value grâce à une fermeture et cette différence ne s'appliquent pas.

L'autre option à envisager est d'utiliser un générateur au lieu d'une compréhension de liste:

def filterbyvalue(seq, value):
   for el in seq:
       if el.attribute==value: yield el

Puis dans votre code principal (qui est l'endroit où la lisibilité est vraiment important que vous avez remplacé à la fois compréhension de liste et le filtre avec un espoir significative nom de la fonction.

259voto

Tendayi Mawushe Points 10335

C'est un peu le problème religieux en Python. Même si Guido considéré supprimant map, filter et reduce de Python 3, il y a suffisamment de jeu qu'à la fin que reduce a été déplacé de built-ins pour functools.réduire.

Personnellement je trouve les interprétations de la liste plus facile à lire. Il est plus explicite ce qui se passe à partir de l'expression [i for i in list if i.attribute == value] comme l'ensemble des comportements est à la surface, pas à l'intérieur de la fonction de filtre.

Je ne voudrais pas trop se soucier de la différence de performances entre les deux approches, comme il est marginal. Je voudrais vraiment que l'optimiser si il s'est avéré être le goulot d'étranglement dans votre application qui est peu probable.

Aussi depuis le BDFL voulais filter disparu de la langue alors sûrement que le fait automatiquement de la liste des compréhensions plus Pythonic ;-)

33voto

Umang Points 2227

Bien que `` peut être la « voie rapide », la « voie Pythonique » serait ne pas se soucier de telles choses, à moins que la performance est absolument critique (auquel cas vous ne serait pas utiliser Python !).

9voto

unbeli Points 9573

J’ai trouver la deuxième manière plus lisible. Il vous dit exactement ce qu’est l’intention : filtrer la liste.
PS : ne pas utiliser « liste » comme nom de variable

8voto

gnibbler Points 103484

généralement `` est légèrement plus rapide si vous utilisez une fonction de builtin.

Je m’attends la compréhension de la liste à être un peu plus vite dans votre cas

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