我有一个如下列表:
a = [4, 5, 0, 0, 6, 7, 0, 1, 0, 5]
我希望将所有零推到该列表的开头。结果必须如下。
a = [0, 0, 0, 0, 4, 5, 6, 7, 1, 5]
如何在Python 2中完成?
答案 0 :(得分:14)
您可以对列表进行排序:
a.sort(key=lambda v: v != 0)
key
函数告诉Python按值排序值是0
。 False
在True
之前排序,然后根据其原始相对位置对值进行排序。
对于0
,返回False
,首先对所有这些值进行排序。其余的True
被返回,留下排序将它们放在最后,但保持其相对位置不变。
演示:
>>> a = [4, 5, 0, 0, 6, 7, 0, 1, 0, 5]
>>> a.sort(key=lambda v: v != 0)
>>> a
[0, 0, 0, 0, 4, 5, 6, 7, 1, 5]
答案 1 :(得分:11)
这可以在没有排序的情况下完成。
初始化:
In [8]: a = [4, 5, 0, 0, 6, 7, 0, 1, 0, 5]
In [9]: from itertools import compress, repeat, chain
list.count
和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]
与之前相同,但没有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]
与上一个相同,但没有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]
对于小清单:
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
对于大型列表:
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
正如您所看到的,在某些情况下,基于itertools
的解决方案往往会变慢,因为函数调用次数很多。
答案 2 :(得分:1)
以下是一些更好的时间,有两种新方法:
SETUP="
from itertools import compress, repeat, chain
a = [4, 5, 0, 0, 6, 7, 0, 1, 0, 5]
"
首先排序:
python -m timeit -s "$SETUP" "a.sort(key=bool)"
# 1000000 loops, best of 3: 1.51 usec per loop
然后霜冻的方法:
python -m timeit -s "$SETUP" "list(chain(repeat(0, a.count(0)), compress(a, a)))"
# 1000000 loops, best of 3: 1.16 usec per loop
python -m timeit -s "$SETUP" "cs = list(compress(a, a)); list(chain(repeat(0, len(a)-len(cs)), cs))"
# 1000000 loops, best of 3: 1.37 usec per loop
然后更直接地从列表中使用的方法:
python -m timeit -s "$SETUP" "[0] * a.count(0) + list(filter(bool, a))"
# 1000000 loops, best of 3: 1.04 usec per loop
python -m timeit -s "$SETUP" "nonzero = list(filter(bool, a)); [0] * (len(a)-len(nonzero)) + nonzero"
# 1000000 loops, best of 3: 0.87 usec per loop
再次使用更大尺寸的输入:
SETUP="
from itertools import compress, repeat, chain
a = [4, 5, 0, 0, 6, 7, 0, 1, 0, 5] * 1000
"
排序:
python -m timeit -s "$SETUP" "a.sort(key=bool)"
# 1000 loops, best of 3: 1.08 msec per loop
frostnational的:
python -m timeit -s "$SETUP" "list(chain(repeat(0, a.count(0)), compress(a, a)))"
# 1000 loops, best of 3: 333 usec per loop
python -m timeit -s "$SETUP" "cs = list(compress(a, a)); list(chain(repeat(0, len(a)-len(cs)), cs))"
# 1000 loops, best of 3: 206 usec per loop
新:
python -m timeit -s "$SETUP" "[0] * a.count(0) + list(filter(bool, a))"
# 1000 loops, best of 3: 295 usec per loop
python -m timeit -s "$SETUP" "nonzero = list(filter(bool, a)); [0] * (len(a)-len(nonzero)) + nonzero"
# 10000 loops, best of 3: 143 usec per loop
尽管相对较慢,Martijn Pieters决定使用排序实际上对于合理大小的列表来说非常具有竞争力,而过早的优化是所有邪恶的根源。
FWIW,这里列出很长的列表:
SETUP="
from itertools import compress, repeat, chain
a = [4, 5, 0, 0, 6, 7, 0, 1, 0, 5] * 1000000
"
python -m timeit -s "$SETUP" "a.sort(key=bool)"
# 10 loops, best of 3: 1.21 sec per loop
python -m timeit -s "$SETUP" "list(chain(repeat(0, a.count(0)), compress(a, a)))"
# 10 loops, best of 3: 347 msec per loop
python -m timeit -s "$SETUP" "cs = list(compress(a, a)); list(chain(repeat(0, len(a)-len(cs)), cs))"
# 10 loops, best of 3: 226 msec per loop
python -m timeit -s "$SETUP" "[0] * a.count(0) + list(filter(bool, a))"
# 10 loops, best of 3: 310 msec per loop
python -m timeit -s "$SETUP" "nonzero = list(filter(bool, a)); [0] * (len(a)-len(nonzero)) + nonzero"
# 10 loops, best of 3: 153 msec per loop
答案 3 :(得分:0)
from collections import deque
a = [4, 5, 0, 0, 6, 7, 0, 1, 0, 5]
b = deque([x for x in a if x!=0])
for i in a:
if i==0:
b.appendleft(0)
print list(b)
#output -> [0, 0, 0, 0, 4, 5, 6, 7, 1, 5]