Python Language Filtre de refactoring et carte pour lister les compréhensions


Exemple

Les fonctions de filter ou de map doivent souvent être remplacées par des listes compréhensibles . Guido Van Rossum le décrit bien dans une lettre ouverte en 2005 :

filter(P, S) est presque toujours écrit plus clair que [x for x in S if P(x)] , ce qui a l'énorme avantage que les usages les plus courants impliquent prédicats des comparaisons, par exemple x==42 , et définissant un lambda pour cela nécessite juste beaucoup plus d'effort pour le lecteur (plus le lambda est plus lent que la compréhension de la liste). Encore plus pour la map(F, S) qui devient [F(x) for x in S] . Bien sûr, dans de nombreux cas, vous pourriez utiliser des expressions de générateur à la place.

Les lignes de code suivantes sont considérées comme " non pythoniques " et provoquent des erreurs dans de nombreux linters en python.

filter(lambda x: x % 2 == 0, range(10)) # even numbers < 10
map(lambda x: 2*x, range(10)) # multiply each number by two
reduce(lambda x,y: x+y, range(10)) # sum of all elements in list

En prenant ce que nous avons appris de la citation précédente, nous pouvons décomposer ces expressions de filter et de map dans leurs compréhensions de liste équivalentes; aussi supprimer les fonctions lambda de chaque - rendant le code plus lisible dans le processus.

# Filter:
# P(x) = x % 2 == 0
# S = range(10)
[x for x in range(10) if x % 2 == 0]

# Map
# F(x) = 2*x
# S = range(10)
[2*x for x in range(10)]

La lisibilité devient encore plus évidente dans le cas des fonctions de chaînage. En raison de la lisibilité, les résultats d'une carte ou d'une fonction de filtre doivent être transmis à la suite; avec des cas simples, ceux-ci peuvent être remplacés par une seule compréhension de liste. De plus, nous pouvons facilement comprendre, à partir de la compréhension de la liste, le résultat de notre processus, où il y a plus de charge cognitive lors du raisonnement sur le processus Map & Filter enchaîné.

# Map & Filter
filtered = filter(lambda x: x % 2 == 0, range(10))
results = map(lambda x: 2*x, filtered)

# List comprehension
results = [2*x for x in range(10) if x % 2 == 0]

Refactoring - Référence rapide

  • Carte

    map(F, S) == [F(x) for x in S]
    
  • Filtre

    filter(P, S) == [x for x in S if P(x)]
    

F et P sont des fonctions qui transforment respectivement les valeurs d'entrée et renvoient un bool