azzamsa
azzamsa

Reputation: 2125

How to remove only zero digit from python list?

I want to remove 0 only from my list:

>>> mylist = [0, 1, None, 2, False, 1, 0]

All of them missing False items

>>> list(filter(lambda x: x != 0, mylist))
[1, None, 2, 1]  # missing False

>>> list(filter(lambda x: x != 0 and x is not type(int), mylist))
[1, None, 2, 1] # missing False

>>> list(filter(lambda x: x != 0 and x is not type(False), mylist))
[1, None, 2, 1]

>>> list(filter(lambda x: x != 0 and x is not False, mylist))
[1, None, 2, 1]

Desired output:

[1, None, 2, False, 1]

Thanks for the help.

Upvotes: 4

Views: 484

Answers (4)

Austin
Austin

Reputation: 26037

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]

Upvotes: 7

E. Ducateme
E. Ducateme

Reputation: 4248

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.

Upvotes: -1

Yaman Jain
Yaman Jain

Reputation: 1247

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]

Upvotes: 1

Shababb Karim
Shababb Karim

Reputation: 3733

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

Upvotes: 0

Related Questions