我必须编写一个程序,该程序给出列表中所有零脉冲的长度(仅包括一个零)。例如
[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]作为输出。任何帮助将不胜感激!
答案 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]