'How to split list into sublists of zeros and nonzero values

For this given list:

a = [1, 0, 0, 1, 1, 1, 3, 0,
     1, 1, 4, 2, 1, 1, 2, 1, 1, 1, 1,
     0, 1, 0, 1, 1, 1, 0, 0, 0, 1, 5]

I would like to split the list into sublists of zeros and nonzero values to have the desired output of

a = [[1], [0,0], [1,1,1,3], [0],
     [1,1,3,2,1,1,2,1,1,1,1,],
     [0], [1], [0], [1,1,1], [0,0,0], [1,5]]

I know how to split a list into a certain length of sublists, but I don't think I can use that method here...



Solution 1:[1]

You can use itertools.groupby

from itertools import groupby

a = [list(g) for k, g in groupby(a, lambda x:x>0)]

groupby(a, lambda x:x>0) groups successive 0 values or non-zero values together.

Above only handles non-negative values. Improvement from FreddyMcloughlan comment to handle all integers.

a = [list(g) for k, g in groupby(a, lambda x:x!=0)]

Solution 2:[2]

You can just iterate over each value, and keep a buffer c and append the buffer to b when the element changes from 0 to a number > 0:

b = []
c = [a[0]]

for i in a[1:]:
    if (c[-1] > 0 and i > 0) or (c[-1] == 0 and i == 0):
        # Continue run
        c.append(i)
    else:
        b.append(c)
        c = [i]

b.append(c)

i.e. The conditional checks to see if the buffer c has changed from a non-zero array to a > 0 array (and vice versa) and if it has not changed, you extend the buffer. When it has changed, append c to b (where b is the final array) then change the buffer to the next value i.


Edit

Your example only includes positive and zero values. If by "nonzero" you are including negative numbers with positive numbers, you can use:

b = []
c = [a[0]]

for i in a[1:]:
    # Use != 0, rather than > 0
    if (c[-1] != 0 and i != 0) or (c[-1] == 0 and i == 0):
        # Continue run
        c.append(i)
    else:
        b.append(c)
        c = [i]

b.append(c)
# Negative values:
>>> a = [1, 0, 0, 1, -1, 1, 3, 0,
...      1, 1, 4, 2, 1, 1, 2, 1, 1, 1, 1,
...      0, 1, 0, 1, 1, 1, 0, 0, 0, -1, 5]
# Run algorithm above
>>> b
[[1], [0, 0], [1, -1, 1, 3], [0],
 [1, 1, 4, 2, 1, 1, 2, 1, 1, 1, 1],
 [0], [1], [0], [1, 1, 1], [0, 0, 0], [-1, 5]]

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2