rwolst
rwolst

Reputation: 13672

List of non-zero elements in a list in Python

Given the list

a = [6, 3, 0, 0, 1, 0]

What is the best way in Python to return the list

b = [1, 1, 0, 0, 1, 0]

where the 1's in b correspond to the non-zero elements in a. I can think of running a for loop and simply appending onto b, but I'm sure there must be a better way.

Upvotes: 7

Views: 8481

Answers (7)

Inbar Rose
Inbar Rose

Reputation: 43447

For completeness, and since no one else added this answer:

b = map(bool, a)

But it returns Boolean values and not Integers.

Upvotes: 2

Jon Clements
Jon Clements

Reputation: 142156

And for the heck of it, another way:

[{0: 0}.get (el, 1) for el in your_list]

Upvotes: 0

user1151446
user1151446

Reputation: 2025

You can also, depending on your application, work with numpy array representation:

$ import numpy as np
$ a = [6, 3, 0, 0, 1, 0]
$ (np.array(a)!= 0).astype(int)
array([1, 1, 0, 0, 1, 0])

astype(int) is only necessary if you dont't want a boolean representation

Upvotes: 1

Colonel Panic
Colonel Panic

Reputation: 137594

Another way

>>> a = [6, 3, 0, 0, 1, 0]

>>> [cmp(x,0) for x in a]
[1, 1, 0, 0, 1, 0]

Note that cmp(x,0) returns -1 for negative numbers, so you might want to abs that.

Upvotes: 1

Colonel Panic
Colonel Panic

Reputation: 137594

How about

>>> a = [6, 3, 0, 0, 1, 0]

>>> [bool(x) for x in a]
[True, True, False, False, True, False]

>>> [int(bool(x)) for x in a]
[1, 1, 0, 0, 1, 0]

Depending what you want it for, you might be better with the boolean list.

Upvotes: 1

Inbar Rose
Inbar Rose

Reputation: 43447

List comprehension method:

a = [6, 3, 0, 0, 1, 0]
b = [1 if i else 0 for i in a]
print b
>>> 
[1, 1, 0, 0, 1, 0]

Timing mine, Dave's method and Lattyware's slight alteration:

$ python3 -m timeit -s "a = [6, 3, 0, 0, 1, 0]" "[1 if i else 0 for i in a]"
1000000 loops, best of 3: 0.838 usec per loop
$ python3 -m timeit -s "a = [6, 3, 0, 0, 1, 0]" "[int(i != 0) for i in a]"
100000 loops, best of 3: 2.15 usec per loop
$ python3 -m timeit -s "a = [6, 3, 0, 0, 1, 0]" "[i != 0 for i in a]"
1000000 loops, best of 3: 0.794 usec per loop

Looks like my method is twice as fast ... I am actually surprised it is that much faster. Taking out the int() call, however, makes the two essentially the same - but leaves the resulting list full of Booleans instead of Integers (True/False instead of 1/0)

Upvotes: 11

dave
dave

Reputation: 12806

b = [int(i != 0) for i in a]

Will give you what you are looking for.

Upvotes: 5

Related Questions