从列表末尾剪切零

时间:2015-02-28 00:04:04

标签: python list python-3.x

函数在参数列表中接收,最后有很多0,如:

[48, 39, 23, 15, 11, 12, 5, 9, 7, 3, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0]
[137, 30, 12, 3, 1, 0, 0, 0]

如果列表的长度和末尾的零数总是不同,我怎样才能将它从零中修剪得到

[48, 39, 23, 15, 11, 12, 5, 9, 7, 3, 4, 2, 0, 0, 1, 0 , 1]
[137, 30, 12, 3, 1]

6 个答案:

答案 0 :(得分:5)

list1 = [48, 39, 23, 15, 11, 12, 5, 9, 7, 3, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0]
list2 = [137, 30, 12, 3, 1, 0, 0, 0]


def pop_zeros(items):
    while items[-1] == 0:
        items.pop()

pop_zeros(list1)
pop_zeros(list2)
print(list1)
print(list2)

输出

[48, 39, 23, 15, 11, 12, 5, 9, 7, 3, 0, 0, 1, 0, 1]
[137, 30, 12, 3, 1]

答案 1 :(得分:3)

如果你想使用弹出的元素,通常会使用最有效的方法来使用反转和删除,弹出:

def remove_zeros(l):
    for ele in reversed(l):
        if not ele:
            del l[-1]
        else:
            break

使用python2.7的一些时间:

In [15]: %%timeit 
li = [48, 39, 23, 15, 11, 12, 5, 9, 7, 3, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0] + [0 for _ in range(1000)]
li[:]=li[0:-len(list(it.takewhile(lambda x: x==0, reversed(li))))]
   ....: 
10000 loops, best of 3: 170 µs per loop

In [16]: %%timeit
l = [48, 39, 23, 15, 11, 12, 5, 9, 7, 3, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0] + [0 for _ in range(1000)]
remove_zeros(l)
   ....: 
10000 loops, best of 3: 103 µs per loop

In [18]: %%timeit
l = [48, 39, 23, 15, 11, 12, 5, 9, 7, 3, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0] + [0 for _ in range(1000)]
pop_zeros(l)
   ....: 
10000 loops, best of 3: 160 µs per loop

如果您喜欢修剪方法,可以使用numpy.trim_zeros

import numpy as np

lst = [48, 39, 23, 15, 11, 12, 5, 9, 7, 3, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0]
lst[:] = np.trim_zeros(lst)
lst
[48, 39, 23, 15, 11, 12, 5, 9, 7, 3, 0, 0, 1, 0, 1]


In [10]: %%timeit 
lst = [48, 39, 23, 15, 11, 12, 5, 9, 7, 3, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0] + [0 for _ in range(1000)]
lst[:] = np.trim_zeros(lst)
   ....: 
10000 loops, best of 3: 150 µs per loop

使用python3.4进行计时并使用ele == 0来避免在列表包含除数字以外的任何内容时删除其他可能的假值:

In [10]: %%timeit
l = [48, 39, 23, 15, 11, 12, 5, 9, 7, 3, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0] + [0 for _ in range(1000)]
pop_zeros(l)
   ....: 
1000 loops, best of 3: 202 µs per loop

In [11]: %%timeit
l = [48, 39, 23, 15, 11, 12, 5, 9, 7, 3, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0] + [0 for _ in range(1000)]
remove_zeros(l)
   ....: 
10000 loops, best of 3: 131 µs per loop
In [12]: %%timeit
li = [48, 39, 23, 15, 11, 12, 5, 9, 7, 3, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0] + [0 for _ in range(1000)]
li[:]=li[0:-len(list(it.takewhile(lambda x: x==0, reversed(li))))]
   ...: 
1000 loops, best of 3: 217 µs per loop

答案 2 :(得分:2)

你可以在while循环中弹出元素,并在element != 0

时打破循环
while mylist:
    if mylist[-1] != 0:
        break
    del mylist[-1]

或者,反向遍历列表并批量删除 slice

for i, j in enumerate(reversed(mylist)):
    if j != 0 and i == 0:
        break
    elif j != 0:
        del mylist[-i:]
        break

编辑:在以前的版本中,我提议mylist = mylist[0:-i]而不是del mylist[-i:]。第一个声明切片&将列表复制到新变量,而后者修改列表。后者更有效率。

答案 3 :(得分:2)

使用itertools takewhile和切片分配的另一种方式:

>>> li=[48, 39, 23, 15, 11, 12, 5, 9, 7, 3, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0]
>>> import itertools as it
>>> li[:]=li[0:-len(list(it.takewhile(lambda x: x==0, reversed(li))))]
>>> li
[48, 39, 23, 15, 11, 12, 5, 9, 7, 3, 0, 0, 1, 0, 1]

答案 4 :(得分:0)

您可以为此使用numpy。

>> import numpy as np
>> a = [1,1,1,3,4,0,4,4,0,0]
>> np.trim_zeroes(a,'b')
[0, 0, 1, 1, 1, 3, 4, 0, 4, 4]

查看文档https://docs.scipy.org/doc/numpy/reference/generated/numpy.trim_zeros.html

答案 5 :(得分:-1)

def rstrip(lst, value):
    for i, x in enumerate(reversed(lst)):
        if x != value:
           if i:
              del lst[-i:]
           return

del lst[-i:]可能比多个lst.pop()更有效:

$ python -mtimeit -s 'from list_rstrip import rstrip, zpop; L=[0]*'1000000 'M=L[:]; rstrip(M, 0)'
10 loops, best of 3: 55.2 msec per loop
$ python -mtimeit -s 'from list_rstrip import rstrip, zpop; L=[0]*'1000000 'M=L[:]; zpop(M)'
10 loops, best of 3: 133 msec per loop
$ python -mtimeit -s 'from list_rstrip import remove_zeros; L=[0]*'1000000 'M=L[:]; remove_zeros(M)'
10 loops, best of 3: 81.4 msec per loop

其中zpop()

def zpop(lst):
    while lst and lst[-1] == 0:
        lst.pop()