web-dev-qa-db-fra.com

supprimer la valeur Aucune de la liste sans supprimer la valeur 0

C'est 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 que le 0 fait toute la différence.

Comment supprimer la valeur None d'une liste sans supprimer la valeur 0?

216
mongotop
>>> L = [0, 23, 234, 89, None, 0, 35, 9]
>>> [x for x in L if x is not None]
[0, 23, 234, 89, 0, 35, 9]

Juste pour le plaisir, voici comment vous pouvez adapter filter pour le faire sans utiliser de lambda, (je ne recommanderais pas ce code - c'est uniquement à des fins scientifiques)

>>> from operator import is_not
>>> from functools import partial
>>> L = [0, 23, 234, 89, None, 0, 35, 9]
>>> filter(partial(is_not, None), L)
[0, 23, 234, 89, 0, 35, 9]
307
jamylak

FWIW, Python 3 rend ce problème facile:

>>> L = [0, 23, 234, 89, None, 0, 35, 9]
>>> list(filter(None.__ne__, L))
[0, 23, 234, 89, 0, 35, 9]

Dans Python 2, vous utiliseriez une liste de compréhension:

>>> [x for x in L if x is not None]
[0, 23, 234, 89, 0, 35, 9]
117
Raymond Hettinger

Pour Python 2.7 (voir la réponse de Raymond, pour Python 3 équivalent):

Vouloir savoir si quelque chose "n'est pas Aucun" est si courant dans python (et d'autres langages OO), que dans mon Common.py (que j'importe dans chaque module avec "from Importation commune * "), j'inclus ces lignes:

def exists(it):
    return (it is not None)

Ensuite, pour supprimer des éléments Aucun de la liste, procédez comme suit:

filter(exists, L)

Je trouve cela plus facile à lire que la compréhension de la liste correspondante (ce que montre Raymond, sa version Python 2).

15
ToolmakerSteve

En utilisant la compréhension par liste, cela peut être fait comme suit:

l = [i for i in my_list if i is not None]

La valeur de l est:

[0, 23, 234, 89, 0, 35, 9]
12
DotPi

La réponse de @jamylak est plutôt agréable. Toutefois, si vous ne souhaitez pas importer quelques modules uniquement pour effectuer cette tâche simple, écrivez votre propre lambda in-place:

>>> L = [0, 23, 234, 89, None, 0, 35, 9]
>>> filter(lambda v: v is not None, L)
[0, 23, 234, 89, 0, 35, 9]
10
A T

Itération vs Espace , l'utilisation pourrait poser problème. Dans différentes situations, le profilage peut indiquer soit "plus rapidement" et/ou "moins de mémoire".

# first
>>> L = [0, 23, 234, 89, None, 0, 35, 9, ...]
>>> [x for x in L if x is not None]
[0, 23, 234, 89, 0, 35, 9, ...]

# second
>>> L = [0, 23, 234, 89, None, 0, 35, 9]
>>> for i in range(L.count(None)): L.remove(None)
[0, 23, 234, 89, 0, 35, 9, ...]

La première approche (comme le suggère également @ jamylak , @ Raymond Hettinger , et - @ Dipto ) crée une liste en double dans la mémoire, ce qui pourrait coûter cher pour une longue liste avec peu d'entrées None.

L'approche seconde parcourt la liste une fois, puis de nouveau à chaque fois jusqu'à atteindre la valeur None. Cela pourrait nécessiter moins de mémoire, et la liste deviendra de plus en plus petite au fur et à mesure. La réduction de la taille de la liste peut accélérer les opérations pour beaucoup de None au début, mais le pire des cas serait si de nombreuses entrées None se trouvaient à l'arrière.

La parallélisation et les techniques in-situ sont d'autres approches, mais chacune a ses propres complications en Python. Connaître les données et les cas d'utilisation à l'exécution, ainsi que le profilage du programme sont un point de départ idéal pour les opérations intensives ou les données volumineuses.

Le choix de l'une ou l'autre approche n'aura probablement aucune importance dans les situations courantes. Cela devient plus une préférence de notation. En fait, dans ces circonstances inhabituelles, numpy ou cython peuvent constituer des alternatives intéressantes au lieu de tenter de microgérer _ les optimisations Python.

5
Kevin

Si tout est 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 cependant

no_none_val = [x[0] for x in L if x[0] is not None] """ Both returns [123, 151]"""

<< list_indice [0] pour variable dans List si variable n'est pas None >>

2
screaminghard
from operator import is_not
from functools import partial   

filter_null = partial(filter, partial(is_not, None))

# A test case
L = [1, None, 2, None, 3]
L = list(filter_null(L))
2
med_abidi

Dites que la liste est comme ci-dessous

iterator = [None, 1, 2, 0, '', None, False, {}, (), []]

Ceci ne renverra que les éléments dont bool(item) is True

print filter(lambda item: item, iterator)
# [1, 2]

Ceci est équivalent à

print [item for item in iterator if item]

Pour filtrer simplement Aucun:

print filter(lambda item: item is not None, iterator)
# [1, 2, 0, '', False, {}, (), []]

Équivalent à:

print [item for item in iterator if item is not None]

Pour obtenir tous les éléments qui ont pour résultat False

print filter(lambda item: not item, iterator)
# Will print [None, '', 0, None, False, {}, (), []]
1
theBuzzyCoder