Move all zeroes to the beginning of a list in Python

后端 未结 4 1226
-上瘾入骨i
-上瘾入骨i 2020-11-29 13:00

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

4条回答
  •  刺人心
    刺人心 (楼主)
    2020-11-29 13:12

    This can be done without sorting.

    Solutions

    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]
    

    Benchmarks

    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.

提交回复
热议问题