remove None value from a list without removing the 0 value

Question:

This was my source I started with.

My List

L = [0, 23, 234, 89, None, 0, 35, 9]

When I run this :

L = filter(None, L)

I get this results

[23, 234, 89, 35, 9]

But this is not what I need, what I really need is :

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

Because I’m calculating percentile of the data and the 0 make a lot of difference.

How to remove the None value from a list without removing 0 value?

Asked By: mongotop

||

Answers:

>>> 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]

Just for fun, here’s how you can adapt filter to do this without using a lambda, (I wouldn’t recommend this code – it’s just for scientific purposes)

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

Using list comprehension this can be done as follows:

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

The value of l is:

[0, 23, 234, 89, 0, 35, 9]
Answered By: DotPi

A list comprehension is likely the cleanest way:

>>> 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]

There is also a functional programming approach but it is more involved:

>>> from operator import is_not
>>> from functools import partial
>>> L = [0, 23, 234, 89, None, 0, 35, 9]
>>> list(filter(partial(is_not, None), L))
[0, 23, 234, 89, 0, 35, 9]
Answered By: Raymond Hettinger

For Python 2.7 (See Raymond’s answer, for Python 3 equivalent):

Wanting to know whether something “is not None” is so common in python (and other OO languages), that in my Common.py (which I import to each module with “from Common import *”), I include these lines:

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

Then to remove None elements from a list, simply do:

filter(exists, L)

I find this easier to read, than the corresponding list comprehension (which Raymond shows, as his Python 2 version).

Answered By: ToolmakerSteve

@jamylak answer is quite nice, however if you don’t want to import a couple of modules just to do this simple task, write your own 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]
Answered By: A T

Iteration vs Space, usage could be an issue. In different situations profiling may show either to be "faster" and/or "less memory" intensive.

# 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, ...]

The first approach (as also suggested by @jamylak, @Raymond Hettinger, and @Dipto) creates a duplicate list in memory, which could be costly of memory for a large list with few None entries.

The second approach goes through the list once, and then again each time until a None is reached. This could be less memory intensive, and the list will get smaller as it goes. The decrease in list size could have a speed up for lots of None entries in the front, but the worst case would be if lots of None entries were in the back.

The second approach would likely always be slower than the first approach. That does not make it an invalid consideration.

Parallelization and in-place techniques are other approaches, but each have their own complications in Python. Knowing the data and the runtime use-cases, as well profiling the program are where to start for intensive operations or large data.

Choosing either approach will probably not matter in common situations. It becomes more of a preference of notation. In fact, in those uncommon circumstances, numpy (example if L is numpy.array: L = L[L != numpy.array(None) (from here)) or cython may be worthwhile alternatives instead of attempting to micromanage Python optimizations.

Answered By: Kevin
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))
Answered By: med_abidi

Say the list is like below

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

This will return only those items whose bool(item) is True

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

This is equivalent to

print [item for item in iterator if item]

To just filter None:

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

Equivalent to:

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

To get all the items that evaluate to False

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

If it is all a list of lists, you could modify sir @Raymond’s answer

L = [ [None], [123], [None], [151] ]
no_none_val = list(filter(None.__ne__, [x[0] for x in L] ) )

for python 2 however

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

<< list_indice[0] for variable in List if variable is not None >>

Answered By: Skrmnghrd
L = [0, 23, 234, 89, None, 0, 35, 9] 
result = list(filter(lambda x: x is not None, L))
Answered By: balaji dileep kumar

If the list has NoneType and pandas._libs.missing.NAType objects than use:

[i for i in lst if pd.notnull(i)]
Answered By: Sedrak Vardanyan