C'était ma source avec laquelle j'ai commencé.
Ma liste
L = [0, 23, 234, 89, None, 0, 35, 9]
Quand je lance ceci:
L = filter(None, L)
J'obtiens ces résultats
[23, 234, 89, 35, 9]
Mais ce n'est pas ce dont j'ai besoin, ce dont j'ai vraiment besoin c'est:
[0, 23, 234, 89, 0, 35, 9]
Parce que je calcule le centile des données et le 0 fait beaucoup de différence.
Comment supprimer la valeur None d'une liste sans supprimer la valeur 0?
filter
version moins élégante :filter(lambda x: x is not None, L)
- Vous pourriez vous débarrasser de l'lambda
utilisationpartial
etoperator.is_not
je pense, mais ça ne vaut probablement pas la peine car la liste-comp est tellement plus propre.is_not
existait! Je pensais que c'était seulementis_
, je vais ajouter ça juste pour le plaisiris_not
exister et d'not_in
exister. En fait, je pense que celanot_in
devrait être transformé en une méthode magique__not_contains__
... voir une question que j'ai posée il y a un certain temps et un commentaire que j'ai fait à un répondeur ... et je n'ai toujours pas l'impression que c'est résolu.filterfalse
ou quelque chose en fonction du cas d'utilisationx > y
cela n'implique pasnot x <= y
en python parce que vous pouvez faire quoi que ce soit dedans__lt__
et__le__
, alors pourquoi devraitx not in y
impliquernot x in y
(d'autant plusnot in
qu'il a son propre bytecode?)FWIW, Python 3 facilite ce problème:
En Python 2, vous utiliseriez plutôt une compréhension de liste:
la source
__ne__
comme ça plutôt quepartial
etne
?operator
module.__ne__
?x != y
appelle en internex.__ne__(y)
où ne signifie "non égal". IlNone.__ne__
s'agit donc d'une méthode liée qui renvoie True lorsqu'elle est appelée avec une valeur autre que None . Par exemple,bm = None.__ne__
appelé avecbm(10)
renvoie NotImplemented qui a la valeur true etbm(None)
renvoie False .En utilisant la compréhension de la liste, cela peut être fait comme suit:
La valeur de l est:
la source
Pour Python 2.7 (Voir la réponse de Raymond, pour l'équivalent Python 3):
Vouloir savoir si quelque chose "n'est pas None" est si courant en python (et dans d'autres langages OO), que dans mon Common.py (que j'importe dans chaque module avec "from Common import *"), j'inclus ces lignes:
Ensuite, pour supprimer les éléments None d'une liste, faites simplement:
Je trouve cela plus facile à lire que la compréhension de la liste correspondante (que Raymond montre, comme sa version Python 2).
la source
partial(is_not, None)
cette solution. Je crois que ce sera plus lent (bien que ce ne soit pas trop important). Mais avec quelques importations de modules python, pas besoin de fonction définie dans ce casLa réponse de @jamylak est assez agréable, cependant si vous ne voulez pas importer quelques modules juste pour faire cette tâche simple, écrivez votre propre
lambda
sur place:la source
[x for x in L if x is not None]
l'autre code n'était qu'un ajout que j'ai explicitement déclaré que je ne recommanderais pasItération vs espace , l'utilisation pourrait être un problème. Dans différentes situations, le profilage peut s'avérer être "plus rapide" et / ou "moins gourmand en mémoire".
La première approche (comme le suggèrent également @jamylak , @Raymond Hettinger et @Dipto ) crée une liste en double en mémoire, ce qui pourrait être coûteux pour une grande liste avec peu
None
entrées.La deuxième approche parcourt la liste une fois, puis à chaque fois jusqu'à ce que a
None
soit atteint. Cela pourrait être moins gourmand en mémoire et la liste se réduira au fur et à mesure. La diminution de la taille de la liste pourrait avoir une accélération pour de nombreusesNone
entrées à l'avant, mais le pire des cas serait si beaucoup deNone
entrées étaient à l'arrière.La parallélisation et les techniques sur place sont d'autres approches, mais chacune a ses propres complications en Python. Connaître les données et les cas d'utilisation d'exécution, ainsi que le profilage du programme sont où commencer pour des opérations intensives ou des données volumineuses.
Le choix de l'une ou l'autre approche n'aura probablement pas d'importance dans les situations courantes. Cela devient plus une préférence de notation. En fait, dans ces circonstances inhabituelles,
numpy
oucython
peuvent être des alternatives valables au lieu de tenter de microgérer les optimisations Python.la source
L.count(None)
et vous appelez.remove(None)
plusieurs fois, ce qui rendO(N^2)
la situation que vous essayez de résoudre ne doit pas être traitée de cette manière, les données doivent être restructurées dans une base de données ou un fichier à la place si la mémoire est importante.O(n^2)
est uniquement lorsque la liste entière estNone
.numpy
serait capable de gérer ce type d'opération de manière plus optimiséenumpy
ces dernières années, mais c'est une compétence distincte. SiL
est instancié en tant quenumpy.array
au lieu d'un Pythonlist
, alorsL = L[L != numpy.array(None)]
(stackoverflow.com/a/25255015/3003133) est probablement meilleur que l'un ou l'autre, mais je ne connais pas les détails d'implémentation pour le traitement par rapport à la mémoire en dessous. Il crée au moins un tableau de longueur en double de booléens pour le masque. La syntaxe d'une comparaison à l'intérieur d'un opérateur d'accès (index), de cette façon, est nouvelle pour moi. Cette discussion a également attiré mon attentiondtype=object
.la source
S'il ne s'agit que d'une liste de listes, vous pouvez modifier la réponse de monsieur @ Raymond
L = [ [None], [123], [None], [151] ] no_none_val = list(filter(None.__ne__, [x[0] for x in L] ) )
pour python 2 cependantno_none_val = [x[0] for x in L if x[0] is not None] """ Both returns [123, 151]"""
<< list_indice [0] pour la variable dans la liste si la variable n'est pas Aucune >>
la source
Dites que la liste est comme ci-dessous
Cela ne retournera que les articles dont
bool(item) is True
Cela équivaut à
Pour filtrer simplement Aucun:
Équivalent à:
Pour obtenir tous les éléments évalués comme faux
la source