I have a list like below:
a = [4, 5, 0, 0, 6, 7, 0, 1, 0, 5]
and I want to push all zeroes to the beginning of that list. The result must
This can be done without sorting.
Initialization:
In [8]: a = [4, 5, 0, 0, 6, 7, 0, 1, 0, 5]
In [9]: from itertools import compress, repeat, chain
list.count and itertools.compress
In [10]: x = [0] * a.count(0); x.extend(compress(a, a))
In [11]: x
Out[11]: [0, 0, 0, 0, 4, 5, 6, 7, 1, 5]
Same as before, but without list.count
In [12]: c = list(compress(a, a)); [0] * (len(a) - len(c)) + c
Out[12]: [0, 0, 0, 0, 4, 5, 6, 7, 1, 5]
list.count, itertools.compress, itertools.repeat, itertools.chain
In [13]: list(chain(repeat(0, a.count(0)), compress(a, a)))
Out[13]: [0, 0, 0, 0, 4, 5, 6, 7, 1, 5]
Same as the previous one, but without list.count
In [14]: c = list(compress(a, a)); list(chain(repeat(0, len(a) - len(c)), c))
Out[14]: [0, 0, 0, 0, 4, 5, 6, 7, 1, 5]
For small lists:
In [21]: %timeit x = [0] * a.count(0); x.extend(compress(a, a))
1000000 loops, best of 3: 583 ns per loop
In [22]: %timeit c = list(compress(a, a)); [0] * (len(a) - len(c)) + c
1000000 loops, best of 3: 661 ns per loop
In [23]: %timeit list(chain(repeat(0, a.count(0)), compress(a, a)))
1000000 loops, best of 3: 762 ns per loop
In [24]: %timeit c = list(compress(a, a)); list(chain(repeat(0, len(a) - len(c)), c))
1000000 loops, best of 3: 900 ns per loop
For large lists:
In [28]: a *= 10000000
In [29]: %timeit x = [0] * a.count(0); x.extend(compress(a, a))
1 loops, best of 3: 1.43 s per loop
In [30]: %timeit c = list(compress(a, a)); [0] * (len(a) - len(c)) + c
1 loops, best of 3: 1.37 s per loop
In [31]: %timeit list(chain(repeat(0, a.count(0)), compress(a, a)))
1 loops, best of 3: 1.79 s per loop
In [32]: %timeit c = list(compress(a, a)); list(chain(repeat(0, len(a) - len(c)), c))
1 loops, best of 3: 1.47 s per loop
As you can see, in some cases itertools-based solutions tend to be slower, because of the big number of function calls.