1) Style presque anglais:
Testez la présence à l'aide de l' in
opérateur, puis appliquez la remove
méthode.
if thing in some_list: some_list.remove(thing)
La remove
méthode supprimera uniquement la première occurrence de thing
, afin de supprimer toutes les occurrences que vous pouvez utiliser à la while
place de if
.
while thing in some_list: some_list.remove(thing)
- Assez simple, probablement mon choix.pour les petites listes (ne peut pas résister à une ligne)
Cette attitude shoot-first-ask-questions-last est courante en Python. Au lieu de tester à l'avance si l'objet convient, il suffit d'effectuer l'opération et de saisir les exceptions pertinentes:
try:
some_list.remove(thing)
except ValueError:
pass # or scream: thing not in some_list!
except AttributeError:
call_security("some_list not quacking like a list!")
Bien sûr, la deuxième clause except dans l'exemple ci-dessus est non seulement d'humour discutable, mais totalement inutile (le but était d'illustrer le typage du canard pour les personnes qui ne connaissent pas le concept).
Si vous vous attendez à plusieurs occurrences de chose:
while True:
try:
some_list.remove(thing)
except ValueError:
break
- un peu bavard pour ce cas d'utilisation spécifique, mais très idiomatique en Python.
- cela fonctionne mieux que # 1
- Le PEP 463 a proposé une syntaxe plus courte pour try / except simple usage qui serait utile ici, mais elle n'a pas été approuvée.
Cependant, avec le gestionnaire de contexte suppress () de contextlib (introduit en python 3.4), le code ci-dessus peut être simplifié comme suit :
with suppress(ValueError, AttributeError):
some_list.remove(thing)
Encore une fois, si vous vous attendez à plusieurs occurrences de chose:
with suppress(ValueError):
while True:
some_list.remove(thing)
3) Style fonctionnel:
Vers 1993, Python a lambda
, reduce()
, filter()
et map()
, avec la permission d'un Lisp hacker qui les a manqués et soumis patches de travail *. Vous pouvez utiliser filter
pour supprimer des éléments de la liste:
is_not_thing = lambda x: x is not thing
cleaned_list = filter(is_not_thing, some_list)
Il existe un raccourci qui peut être utile pour votre cas: si vous souhaitez filtrer les éléments vides (en fait, les éléments où bool(item) == False
, comme None
, zéro, des chaînes vides ou d'autres collections vides), vous pouvez passer None comme premier argument:
cleaned_list = filter(None, some_list)
- [mise à jour] : en Python 2.x,
filter(function, iterable)
utilisé pour être équivalent à [item for item in iterable if function(item)]
(ou [item for item in iterable if item]
si le premier argument l'est None
); en Python 3.x, il est maintenant équivalent à (item for item in iterable if function(item))
. La différence subtile est que le filtre utilisé pour renvoyer une liste, maintenant il fonctionne comme une expression de générateur - c'est OK si vous parcourez seulement la liste nettoyée et la jetez, mais si vous avez vraiment besoin d'une liste, vous devez joindre l' filter()
appel avec le list()
constructeur.
- * Ces constructions aromatisées Lispy sont considérées comme un peu étrangères en Python. Vers 2005, Guido parlait même de supprimer
filter
- avec des compagnons map
et reduce
(ils ne sont pas encore partis mais ont reduce
été déplacés dans le module functools , qui vaut le coup d'œil si vous aimez les fonctions de haut niveau ).
4) Style mathématique:
Les compréhensions de liste sont devenues le style préféré pour la manipulation de liste en Python depuis son introduction dans la version 2.0 par PEP 202 . La raison est que la liste compréhensions fournissent une façon plus concise pour créer des listes dans des situations où map()
et filter()
et / ou des boucles imbriquées seraient actuellement utilisées.
cleaned_list = [ x for x in some_list if x is not thing ]
Les expressions de générateur ont été introduites dans la version 2.4 par PEP 289 . Une expression de générateur est préférable pour les situations où vous n'avez pas vraiment besoin (ou ne voulez pas) d'avoir une liste complète créée en mémoire - comme lorsque vous voulez simplement parcourir les éléments un par un. Si vous parcourez uniquement la liste, vous pouvez considérer une expression de générateur comme une compréhension de liste évaluée paresseuse :
for item in (x for x in some_list if x is not thing):
do_your_thing_with(item)
Remarques
- vous voudrez peut-être utiliser l'opérateur d'inégalité
!=
au lieu de is not
( la différence est importante )
- pour les critiques des méthodes impliquant une copie de liste: contrairement à la croyance populaire, les expressions génératrices ne sont pas toujours plus efficaces que les compréhensions de liste - veuillez profiler avant de vous plaindre