Vous avez une liste de données et souhaitez conserver uniquement les éléments qui répondent à une condition précise ? En Python, la fonction filter() permet de faire ce tri proprement, à condition de bien comprendre son fonctionnement paresseux, ses valeurs booléennes et la différence avec une compréhension de liste. Je présente ici une méthode pratique, des exemples concrets et les erreurs qui reviennent le plus souvent.
Les repères essentiels pour filtrer des données en Python
-
filter()conserve les éléments pour lesquels une fonction renvoie une valeur vraie. - En Python 3, le résultat est un itérateur, qu’il faut souvent convertir en liste.
- Une fonction passée à
filter()est appelée un prédicat lorsqu’elle renvoie vrai ou faux. - La compréhension de liste est souvent plus lisible pour une règle simple.
- Avec de gros volumes, l’évaluation paresseuse peut réduire la mémoire utilisée.

Comprendre ce que renvoie filter()
La syntaxe générale est simple, mais son résultat surprend parfois au début :
filter(fonction, iterable)
La fonction reçoit chaque élément de l’itérable et décide de le conserver ou non. Un itérable peut être une liste, un tuple, un ensemble, un dictionnaire ou même un générateur. Dans la pratique, je retiens cette règle : si la fonction renvoie une valeur évaluée à vrai, l’élément reste dans le résultat.
nombres = [3, 8, 11, 14, 17]
pairs = filter(lambda nombre: nombre % 2 == 0, nombres)
print(list(pairs))
# [8, 14]
En Python 3, filter() ne crée pas immédiatement une nouvelle liste. Il renvoie un objet itérateur qui produit les résultats au fur et à mesure. C’est utile pour économiser de la mémoire, mais cela signifie aussi qu’il faut utiliser list() si l’on souhaite afficher ou réutiliser directement tous les éléments.
| Écriture | Résultat | Usage conseillé |
|---|---|---|
filter(...) |
Itérateur | Parcours progressif ou gros volume de données |
list(filter(...)) |
Liste complète | Affichage, indexation ou réutilisation |
tuple(filter(...)) |
Tuple | Données immuables |
Un point me semble particulièrement important. Un itérateur est généralement consommé une seule fois :
resultat = filter(lambda x: x > 10, [4, 12, 15])
print(list(resultat))
# [12, 15]
print(list(resultat))
# []
Le second affichage est vide parce que les éléments ont déjà été parcourus. Si vous devez consulter le résultat plusieurs fois, convertissez-le dès le départ en liste ou en tuple.
Écrire un prédicat clair et fiable
Le premier argument de filter() peut être une fonction classique, une fonction lambda ou None. Pour une condition courte, la lambda est pratique. Dès que la règle devient un peu métier, je préfère une fonction nommée, plus facile à tester et à relire.
def est_adulte(age):
return age >= 18
ages = [12, 16, 18, 24, 31]
adultes = list(filter(est_adulte, ages))
print(adultes)
# [18, 24, 31]
Cette organisation rend la condition indépendante du filtrage. On peut donc la tester séparément, la réutiliser ailleurs et lui donner un nom qui explique son intention. Un bon prédicat répond clairement à une question, par exemple « cet utilisateur est-il actif ? » ou « ce fichier possède-t-il une extension autorisée ? ».
Filtrer des chaînes de caractères
Pour des mots, la condition peut vérifier la longueur, le contenu ou le format. Il faut cependant traiter les chaînes vides avec attention, car une chaîne vide est considérée comme fausse en Python.
mots = ["Python", "", "réseau", "IA", "sécurité"]
non_vides = list(filter(lambda mot: mot, mots))
longs = list(filter(lambda mot: len(mot) >= 4, mots))
print(non_vides)
# ["Python", "réseau", "IA", "sécurité"]
print(longs)
# ["Python", "réseau", "sécurité"]
Dans le premier cas, filter() retire toutes les valeurs dites falsy, notamment "", None, 0 et False. Cette écriture est concise, mais je l’utilise seulement lorsque cette règle générale est réellement souhaitée. Sinon, une condition explicite évite les mauvaises surprises.
Utiliser None pour supprimer les valeurs vides
valeurs = [0, 12, None, "", "Python", False, 8]
nettoyees = list(filter(None, valeurs))
print(nettoyees)
# [12, "Python", 8]
Cette solution est efficace pour nettoyer rapidement une collection. Elle supprime toutefois le zéro et la valeur False, qui peuvent être des informations valides. Ne l’utilisez pas pour nettoyer des données sensibles au sens métier sans vérifier la signification de chaque valeur.
Filter ou compréhension de liste
Dans beaucoup de scripts Python, la compréhension de liste est plus naturelle que filter(). Les deux approches produisent le même résultat lorsqu’il faut construire immédiatement une liste :
nombres = [3, 8, 11, 14, 17]
avec_filter = list(filter(lambda n: n % 2 == 0, nombres))
avec_comprehension = [n for n in nombres if n % 2 == 0]
print(avec_filter)
print(avec_comprehension)
Personnellement, je choisis la compréhension lorsque la condition est courte et directement lisible. Elle évite la combinaison parfois moins fluide entre filter(), lambda et list(). En revanche, filter() devient intéressant lorsque le prédicat existe déjà sous la forme d’une fonction réutilisable.
| Critère | filter() |
Compréhension de liste |
|---|---|---|
| Lisibilité | Bonne avec une fonction nommée | Excellente pour une condition simple |
| Résultat immédiat | Non, sauf conversion | Oui, sous forme de liste |
| Réutilisation d’une fonction | Très pratique | Moins directe |
| Mémoire | Économe avant conversion | Crée immédiatement une liste |
La différence de vitesse est rarement le facteur principal dans un petit script. Je privilégie donc la clarté. Une expression légèrement plus longue mais évidente sera souvent préférable à une optimisation difficile à comprendre six mois plus tard.
Filtrer des dictionnaires et des données réelles
Les données concrètes sont souvent stockées dans une liste de dictionnaires. Le filtre doit alors accéder à une clé et anticiper les valeurs absentes ou mal typées.
utilisateurs = [
{"nom": "Claire", "actif": True, "age": 29},
{"nom": "Louis", "actif": False, "age": 34},
{"nom": "Nina", "actif": True, "age": 17},
]
actifs = list(filter(lambda utilisateur: utilisateur["actif"], utilisateurs))
print(actifs)
# [{"nom": "Claire", "actif": True, "age": 29},
# {"nom": "Nina", "actif": True, "age": 17}]
Cette version suppose que chaque dictionnaire possède la clé actif. Si les données viennent d’un fichier JSON, d’une API ou d’un formulaire, cette hypothèse peut être fragile. Dans ce cas, get() est souvent plus sûr :
actifs = list(
filter(lambda utilisateur: utilisateur.get("actif", False), utilisateurs)
)
Pour une condition plus précise, une fonction nommée améliore vite la lisibilité :
def profil_eligible(utilisateur):
return (
utilisateur.get("actif", False)
and utilisateur.get("age", 0) >= 18
)
eligibles = list(filter(profil_eligible, utilisateurs))
J’éviterais en revanche d’utiliser filter() pour cacher une transformation complexe. Si le code doit modifier les données, calculer plusieurs champs ou gérer plusieurs cas, une boucle explicite ou une étape séparée sera généralement plus facile à maintenir.
Éviter les erreurs fréquentes
Oublier de convertir le résultat
resultat = filter(lambda x: x > 5, [2, 6, 9])
print(resultat)
#
Voir un objet filter au lieu de la liste attendue est normal. Utilisez list(resultat) pour obtenir les valeurs. Je conseille de faire cette conversion au moment où le programme a réellement besoin d’une collection complète, afin de conserver l’avantage de l’évaluation paresseuse aussi longtemps que possible.
Modifier la liste pendant le filtrage
Il ne faut pas supprimer ou ajouter des éléments à la collection parcourue pendant l’opération. Ce mélange peut produire des résultats incomplets ou difficiles à prévoir. Créez plutôt une nouvelle collection filtrée, puis remplacez l’ancienne si nécessaire.
Lire aussi : Installer pip sous Windows - La méthode fiable et sans erreur
Confondre filtrage et transformation
filter() conserve ou écarte des éléments, mais ne les transforme pas. Pour appliquer une opération à chaque valeur, map() est plus adapté. Pour faire les deux, une compréhension de liste est souvent plus directe :
prix = [10, 20, 30, 40]
resultat = [p * 1.2 for p in prix if p >= 20]
print(resultat)
# [24.0, 36.0, 48.0]
Cette distinction évite beaucoup de code confus. Filtrer signifie choisir, tandis que transformer signifie produire une nouvelle représentation de chaque élément.
Profiter du filtrage paresseux sur de gros volumes
Le comportement paresseux de filter() devient intéressant lorsque la source contient beaucoup de données. Au lieu de créer immédiatement une liste complète, Python ne calcule chaque résultat qu’au moment où il est demandé.
nombres = range(1_000_000)
grands_nombres = filter(lambda n: n > 999_000, nombres)
for nombre in grands_nombres:
print(nombre)
Le programme ne stocke pas un million de résultats filtrés en mémoire. Cela ne rend pas automatiquement l’opération rapide, car la condition est tout de même évaluée sur les éléments parcourus, mais la consommation mémoire reste plus maîtrisée.
Pour arrêter le parcours dès qu’un résultat suffit, combinez l’itérateur avec une fonction comme next() :
nombres = [4, 7, 12, 19]
premier = next(filter(lambda n: n > 10, nombres), None)
print(premier)
# 12
Le second argument de next() fournit une valeur de secours si aucun élément ne correspond. C’est une technique utile lorsque vous cherchez un seul résultat et que vous voulez éviter de construire une liste inutile.
Pour récupérer les éléments qui ne respectent pas une condition, le module standard itertools propose aussi filterfalse(). Cette fonction complète le filtrage classique lorsque l’inversion de la condition rend le code moins lisible.
La bonne décision dépend de la donnée à traiter
Pour une liste courte et une condition simple, je recommande souvent la compréhension de liste. Pour une fonction de validation réutilisable, un parcours paresseux ou une source volumineuse, filter() reste une solution élégante et parfaitement adaptée.
Avant de choisir, vérifiez trois points. La condition doit être facile à comprendre, le type de résultat attendu doit être clair et les valeurs falsy comme 0 ou False ne doivent pas être éliminées par accident. Avec ces précautions, le filtrage en Python devient un outil sobre, prévisible et très pratique pour nettoyer des données, sélectionner des utilisateurs ou préparer un traitement plus complexe.