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
Notez que cela ne supprimera qu'une seule instance de la chaîne vide de votre liste (comme votre code l'aurait fait aussi). Votre liste peut-elle en contenir plusieurs?
la source
Si
index
ne trouve pas la chaîne recherchée, il lance leValueError
que vous voyez. Soit attraper ValueError:ou use
find
, qui renvoie -1 dans ce cas.la source
>>> s [u'Hello', u'Cool', u'Glam'] >>> i = s.find("") Traceback (most recent call last): File "<pyshell#42>", line 1, in <module> i = s.find("") AttributeError: 'list' object has no attribute 'find'
remove()
approche de Time Pietscker est beaucoup plus directe: elle montre directement ce que le code est censé faire (il n'y a en effet pas besoin d'index intermédiairei
).Ajouter cette réponse pour être complet, bien qu'elle ne soit utilisable que sous certaines conditions.
Si vous avez des listes très volumineuses, la suppression de la fin de la liste évite aux internes CPython de le faire
memmove
, dans les situations où vous pouvez réorganiser la liste. Il donne un gain de performances à supprimer de la fin de la liste, car il n'aura pas besoin dememmove
chaque élément après celui que vous supprimez - retour d'une étape (1) .Pour les suppressions ponctuelles, la différence de performances peut être acceptable, mais si vous avez une grande liste et devez supprimer de nombreux éléments - vous remarquerez probablement un impact sur les performances.
Bien que, il est vrai que dans ces cas, effectuer une recherche dans la liste complète est également susceptible d'être un goulot d'étranglement en matière de performances, sauf si les éléments sont principalement en tête de liste.
Cette méthode peut être utilisée pour une suppression plus efficace,
tant que la réorganisation de la liste est acceptable. (2)
Vous souhaiterez peut-être éviter de générer une erreur lorsque le
item
n'est pas dans la liste.set
, surtout si la liste n'est pas destinée à stocker des doublons.En pratique, vous devrez peut-être stocker des données modifiables qui ne peuvent pas être ajoutées à a
set
. Vérifiez également sur btree si les données peuvent être commandées.la source
Eek, ne fais rien de compliqué :)
Juste
filter()
vos tags.bool()
renvoieFalse
pour les chaînes vides, donc au lieu detu devrais écrire
ou mieux encore, mettez cette logique à l'intérieur
striplist()
afin qu'elle ne retourne pas de chaînes vides en premier lieu.la source
striplist
fonction, comment puis-je intégrer votre solution: def striplist (l): "" "supprime les espaces blancs des chaînes dans une liste l" "" return ([x.strip () pour x in l])[x.strip() for x in l if x.strip()]
ou utiliser intégré de Pythonmap
etfilter
fonctionne comme ceci:filter(bool, map(str.strip, l))
. Si vous voulez le tester, évaluer ce dans l'interpréteur interactif:filter(bool, map(str.strip, [' a', 'b ', ' c ', '', ' ']))
.None
place debool
pour le premier argument suffit.Voici une autre approche unilatérale à lancer:
Il ne crée pas de copie de liste, n'effectue pas plusieurs passages dans la liste, ne nécessite pas de gestion d'exception supplémentaire et renvoie l'objet correspondant ou Aucun s'il n'y a pas de correspondance. Le seul problème est que cela fait une longue déclaration.
En général, lorsque vous recherchez une solution à une ligne qui ne lève pas d'exceptions, next () est la voie à suivre, car c'est l'une des rares fonctions Python qui prend en charge un argument par défaut.
la source
Tout ce que vous avez à faire est ceci
mais cette méthode a un problème. Vous devez mettre quelque chose à la place, donc j'ai trouvé ceci:
la source