计算列表中的连续零

时间:2019-06-28 19:54:35

标签: python

我必须编写一个程序,该程序给出列表中所有零脉冲的长度(仅包括一个零)。例如

[1, 0, 0, 0, 0, 3, 7, 0, 0, 0, 0, 0, 0, 50, 0]

会给:

[4, 6, 1]

这是我到目前为止所写的内容:

listsize = int(input("Please enter the length of the list: "))
burstList = []

for i in range(0, listsize):
    N = int(input("Please enter a number: "))
    burstList.append(N)

print("Your final list is: ", burstList)

counter = 0
output = []
burst_open = False
for i in range(len(burstList)):
    if i == 0:
        counter += 1
        burst_open = True
    else:
        if burst_open:
        output.append(counter)
        counter = 0
        burst_open = False
print(output)

我认为这段代码应该可以工作,但是当我在示例列表中运行它时,只给了我[1]作为输出。任何帮助将不胜感激!

4 个答案:

答案 0 :(得分:5)

使用itertools.groupby

In [889]: lst = [1, 0, 0, 0, 0, 3, 7, 0, 0, 0, 0, 0, 0, 50, 0]                                                                                                                                              

In [890]: [len(list(g)) for k, g in itertools.groupby(lst) if k == 0]                                                                                                                                       
Out[890]: [4, 6, 1]

在这里,我们要遍历各个组,并在组键为0时获取每个组的长度。

在上面,我们从迭代器中创建一个列表以获取长度。相反,我们可以通过以下方式获得迭代器的数量,而无需创建中间列表:

In [893]: [sum(1 for _ in g) for k, g in itertools.groupby(lst) if k == 0]                                                                                                                                    
Out[893]: [4, 6, 1]

sum(1 for _ in g)仅消耗迭代器并计算元素,而没有创建仅用于计算其元素的新列表。

就速度而言,两个长度获取解决方案的时间复杂度均为O(N)。但实际上,由于C级循环,list会更快。

答案 1 :(得分:1)

您的for应该在burstList上。

另外,在循环完成后,如果计数器计数器的值不为0,则必须追加计数器(如果数组以0结尾,则永远不会在最后一个脉冲串上达到else条件。

burstList = [1, 0, 0, 0, 0, 3, 7, 0, 0, 0, 0, 0, 0, 50, 0]

counter = 0
output = []
burst_open = False
for i in burstList:
    if i == 0:
        counter += 1
        burst_open = True
    else:
        if burst_open:
            output.append(counter)
        counter = 0
        burst_open = False

if counter !=0:
    output.append(counter)
print(output)

输出:

  

[4,6,1]

答案 2 :(得分:0)

这就是我要做的:

ll = [1, 0, 0, 0, 0, 3, 7, 0, 0, 0, 0, 0, 0, 50, 0]


def value_bursts(items, value=0):
    result = []
    counter = 0
    for item in items:
        if item == value:
            counter += 1
        elif counter > 0:
            result.append(counter)
            counter = 0
    if counter > 0:
        result.append(counter)
    return result


value_bursts(ll)
# [4, 6, 1]

我将其包装到一个函数中,并摆脱了无用的burst_open标志。

请注意,虽然@heemayl的1-liner当然很优雅,但可能不是最快的:

import itertools


def value_bursts_2(items, value=0):
    return [len(list(g)) for k, g in itertools.groupby(items) if k == value]
%timeit value_bursts(ll * 1000)
# 1000 loops, best of 3: 643 µs per loop
%timeit value_bursts_2(ll * 1000)
# 1000 loops, best of 3: 1.11 ms per loop

答案 3 :(得分:0)

除了使用列表理解之外,您还可以通过一个非常简单的循环来生成结果:

result = []
for n in burstList:
    if n == 0 and result   : result[-1]+=1
    elif result[-1:] != [0]: result    += [0**n]

如果您可以使用库函数,可能会更加简洁:

from itertools import accumulate
from collections import Counter

result = [c-1 for c in Counter(accumulate(burstList)).values() if c>1]