I want to remove 0
only from my list:
>>> mylist = [0, 1, None, 2, False, 1, 0]
<
Python bool is a subclass of int
and False
is analogous to 0. Hence compare by equality does not yield desired output.
You can use (Note this is least preferred and you ideally should not use):
>>> list(filter(lambda x: x is not 0, mylist))
[1, None, 2, False, 1]
What you should use:
An identity check may not work out in all cases as discussed in comments. A more feasible way would be to use equality check with type check as:
>>> list(filter(lambda x: x != 0 or isinstance(x, bool), mylist))
[1, None, 2, False, 1]
Personally, not a fan of filter
and lambda
, I would use a list-comprehension which proves faster:
>>> [x for x in mylist if x != 0 or isinstance(x, bool)]
[1, None, 2, False, 1]
The x is not 0
approach works, but is probably not optimal. There speed enhancements by using a list comprehension
instead of using calls to list()
and to filter()
.
Running this in a Jupyter notebook and taking advantage of the builtin %timeit
magic to see how quickly each of these can return the result.
mylist = [0, 1, None, 2, False, 1, 0]
Using list() and filter()
%timeit list(filter(lambda x: x is not 0, mylist))
**1.12 µs** ± 17.7 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
Using a list comprehsion
%timeit [i for i in mylist if i is not 0]
**411 ns** ± 8.42 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
We see that the list comprehension technique is significantly faster.
type bool
is a sub type of int
, so False
translates to 0
. I think an solution is to stringify the number and filter it. There are also good and better answers given here:
list(filter(lambda x: str(x) != '0', mylist))
You can check for data type of x
also and then use !=
operator.
# works for integer 0
[x for x in mylist if type(x) != int or x != 0]
# works for float 0.0 as well
[x for x in mylist if (type(x) != int and type(x) != float) or x != 0]