La fonction Python intégrée filter()
peut être utilisée pour créer un nouvel itérateur à partir d’un itérateur existant (comme une liste ou un dictionnaire) qui filtrera efficacement les éléments en utilisant une fonction que nous fournissons. Un itérable est un objet Python qui peut être « itéré », c’est-à-dire qu’il renvoie des éléments dans une séquence telle que nous pouvons l’utiliser dans une boucle for
.
La syntaxe de base de la fonction filter()
est la suivante :
filter(function, iterable)
Cela permet de renvoyer un objet filtre, qui est un objet itérable. Nous pouvons utiliser une fonction comme list()
pour faire une liste de tous les éléments retournés dans un objet filtre.
La fonction filter()
fournit un moyen de filtrer les valeurs qui peut souvent être plus efficace que la compréhension d’une liste, en particulier lorsque nous commençons à travailler avec des ensembles de données plus importants. Par exemple, la compréhension d’une liste permet de créer une nouvelle liste, ce qui augmente le temps d’exécution de ce traitement. Cela signifie qu’une fois que notre compréhension de la liste aura terminé son expression, nous aurons deux listes en mémoire. Cependant, filter()
fera un objet simple qui contiendra une référence à la liste originale, la fonction fournie, et un index de l’endroit où aller dans la liste originale, ce qui prendra moins de mémoire.
Dans ce tutoriel, nous allons passer en revue quatre façons différentes d’utiliser filter()
: avec deux structures itérables différentes, avec une fonction lambda
et sans fonction définie.
filter()
avec une fonctionLe premier argument de filter()
est une fonction, que nous utilisons pour décider d’inclure ou de filtrer chaque élément. La fonction est appelée une fois pour chaque élément de l’itérable passé en second argument et chaque fois qu’elle renvoie False
, la valeur est abandonnée. Comme cet argument est une fonction, nous pouvons soit passer une fonction normale, soit utiliser des fonctions lambda
, en particulier lorsque l’expression est moins complexe.
Voici la syntaxe d’un lambda
avec filter()
:
filter(lambda item: item[] expression, iterable)
Avec une liste, comme celle qui suit, nous pouvons incorporer une fonction lambda
avec une expression par rapport à laquelle nous voulons évaluer chaque élément de la liste :
creature_names = ['Sammy', 'Ashley', 'Jo', 'Olly', 'Jackie', 'Charlie']
Pour filtrer cette liste afin de trouver les noms de nos créatures d’aquarium qui commencent par une voyelle, nous pouvons exécuter la fonction lambda
suivante :
print(list(filter(lambda x: x[0].lower() in 'aeiou', creature_names)))
Ici, nous déclarons un élément de notre liste sous la forme x
. Ensuite, nous définissons notre expression pour accéder au premier caractère de chaque chaîne (ou caractère « zéro »), donc x [0]
. La mise en minuscule de chacun des noms permet de faire correspondre les lettres à la chaîne de caractères de notre expression, « aeiou
».
Enfin, nous passons l’itérable creature_names
. Comme dans la section précédente, nous appliquons list()
au résultat afin de créer une liste à partir des retours de l’itérateur filter()
.
La sortie sera la suivante :
Output['Ashley', 'Olly']
Ce même résultat peut être obtenu en utilisant une fonction que nous définissons :
creature_names = ['Sammy', 'Ashley', 'Jo', 'Olly', 'Jackie', 'Charlie']
def names_vowels(x):
return x[0].lower() in 'aeiou'
filtered_names = filter(names_vowels, creature_names)
print(list(filtered_names))
Notre fonction names_vowels
définit l’expression que nous allons mettre en œuvre pour filtrer creature_names
.
Là encore, le résultat serait le suivant :
Output['Ashley', 'Olly']
Dans l’ensemble, les fonctions lambda
obtiennent le même résultat avec filter()
que lorsque nous utilisons une fonction normale. La nécessité de définir une fonction normale s’accroît à mesure que la complexité des expressions pour filtrer nos données augmente, ce qui est susceptible de favoriser une meilleure lisibilité dans notre code.
None
avec filter()
Nous pouvons passer None
comme premier argument à filter()
pour que l’itérateur renvoyé filtre toute valeur que Python considère comme « fausse ». En général, Python considère comme faux tout ce qui a une longueur de 0
(comme une liste vide ou une chaîne vide) ou qui est numériquement équivalent à 0
, d’où l’utilisation du terme «fausse».
Dans le cas suivant, nous voulons filtrer notre liste pour n’afficher que les numéros des cuves de notre aquarium :
aquarium_tanks = [11, False, 18, 21, "", 12, 34, 0, [], {}]
Dans ce code, nous avons une liste contenant des nombres entiers, des séquences vides et une valeur booléenne.
filtered_tanks = filter(None, aquarium_tanks)
Nous utilisons la fonction filter()
avec None
et passons dans la liste aquarium_tanks
comme notre itérable. Puisque nous avons retenu l’argument None
, nous allons vérifier si les éléments de notre liste sont considérés comme faux.
print(list(filtered_tanks))
Ensuite, nous enveloppons filtered_tanks
dans une fonction list()
afin qu’elle renvoie une liste pour filtered_tanks
lors de l’impression.
Ici, nous voyons que la sortie ne montre que les nombres entiers. Tous les éléments évalués à False
, qui équivalent à une longueur de 0
, ont été supprimés par filter()
:
Output[11, 25, 18, 21, 12, 34]
Note : Si nous n’utilisions pas list()
et n’imprimions pas filtered_tanks
, nous recevrions un objet filtre qui ressemblerait à quelque chose comme ceci : <filter object at 0x7fafd5903240>
. L’objet filtre est un objet itérable, nous pouvons donc le passer en boucle avec for
ou nous pouvons utiliser list()
pour le transformer en liste, ce que nous faisons ici parce que c’est un bon moyen d’examiner les résultats.
Avec None
, nous avons utilisé filter()
pour retirer rapidement de notre liste les éléments qui étaient considérés comme faux.
filter()
avec une liste de dictionnairesLorsque nous disposons d’une structure de données plus complexe, nous pouvons toujours utiliser filter()
pour évaluer chacun des éléments. Par exemple, si nous disposons d’une liste de dictionnaires, non seulement nous voulons itérer sur chaque élément de la liste, un des dictionnaires, mais nous pouvons aussi vouloir itérer sur chaque paire clé:valeur dans un dictionnaire afin d’évaluer toutes les données.
À titre d’exemple, disons que nous avons une liste de chaque créature dans notre aquarium avec différents détails sur chacune d’entre elles :
aquarium_creatures = [
{"name": "sammy", "species": "shark", "tank number": "11", "type": "fish"},
{"name": "ashley", "species": "crab", "tank number": "25", "type": "shellfish"},
{"name": "jo", "species": "guppy", "tank number": "18", "type": "fish"},
{"name": "jackie", "species": "lobster", "tank number": "21", "type": "shellfish"},
{"name": "charlie", "species": "clownfish", "tank number": "12", "type": "fish"},
{"name": "olly", "species": "green turtle", "tank number": "34", "type": "turtle"}
]
Nous voulons filtrer ces données par une chaîne de recherche que nous donnons à la fonction. Pour que filter()
puisse accéder à chaque dictionnaire et à chaque élément des dictionnaires, nous construisons une fonction imbriquée, comme la suivante :
def filter_set(aquarium_creatures, search_string):
def iterator_func(x):
for v in x.values():
if search_string in v:
return True
return False
return filter(iterator_func, aquarium_creatures)
Nous définissons une fonction filter_set()
qui prend aquarium_creatures
et search_string
comme paramètres. Dans filter_set()
nous passons notre iterator_func()
comme la fonction à filter()
. La fonction filter_set()
renverra l’itérateur résultant de filter()
.
L'iterator_func()
prend x
comme argument, qui représente un élément de notre liste (c’est-à-dire un dictionnaire unique).
Ensuite, la boucle for
accède aux valeurs de chaque paire clé:valeur dans nos dictionnaires et utilise ensuite une déclaration conditionnelle pour vérifier si la chaîne search_string
est en v
, représentant une valeur.
Comme dans nos exemples précédents, si l’expression est considérée comme True
, la fonction ajoute l’élément à l’objet filtre. Elle sera renvoyée une fois que la fonction filter_set()
sera terminée. Nous positionnons le retour False
en dehors de notre boucle afin qu’il vérifie chaque élément de chaque dictionnaire, au lieu de revenir après avoir vérifié le premier dictionnaire seul.
Nous appelons filter_set()
avec notre liste de dictionnaires et la chaîne de recherche pour laquelle nous voulons trouver des correspondances :
filtered_records = filter_set(aquarium_creatures, "2")
Une fois la fonction terminée, nous avons notre objet filtre stocké dans la variable filtered_records
, que nous transformons en liste et imprimons :
print(list(filtered_records))
Nous verrons les résultats suivants de ce programme :
Output[{'name': 'ashley', 'species': 'crab', 'tank number': '25', 'type': 'shellfish'}, {'name': 'jackie', 'species': 'lobster', 'tank number': '21', 'type': 'shellfish'}, {'name': 'charlie', 'species': 'clownfish', 'tank number': '12', 'type': 'fish'}]
Nous avons filtré la liste des dictionnaires avec la chaîne de recherche 2
. Nous pouvons voir que les trois dictionnaires qui comprenaient un numéro de réservoir avec 2
ont été renvoyés. L’utilisation de notre propre fonction imbriquée nous a permis d’accéder à chaque élément et de vérifier efficacement chaque élément par rapport à la chaîne de recherche.
Dans ce tutoriel, nous avons appris les différentes façons d’utiliser la fonction filter()
en Python. Vous pouvez maintenant utiliser filter()
avec votre propre fonction, une fonction lambda
, ou avec None
pour filtrer les éléments de structures de données plus ou moins complexes.
Bien que dans ce tutoriel nous ayons imprimé les résultats de filter()
immédiatement sous forme de liste, il est probable que dans nos programmes nous utiliserions l’objet filter()
renvoyé et manipulerions les données par la suite.
Si vous souhaitez en savoir plus sur Python, consultez notre série Comment coder en Python 3 et notre page thématique Python.
Thanks for learning with the DigitalOcean Community. Check out our offerings for compute, storage, networking, and managed databases.
This textbox defaults to using Markdown to format your answer.
You can type !ref in this text area to quickly search our full set of tutorials, documentation & marketplace offerings and insert the link!