Python 3.x 列表中连续数据的总和-Python

Python 3.x 列表中连续数据的总和-Python,python-3.x,list,Python 3.x,List,我有一个很长的列表,其中一个示例如下所示: L = [0, 1, 2, 0, 0, 2, 3, 1, 0, 10, 0, 2, 4, 5, 0, 0, 7, 8, 9, 0, ...] singleData = [] sumofTwo = [] sumofThree = [] sumofFour = [] . . 我希望能够根据求和操作中涉及的数字计数,将一个数据或两个或多个连续数据的总和分类到相应的列表中。因此,如果两个数字之间出现零,则不考虑它们的和 例如,如果我取上面的列表,1和2的

我有一个很长的列表,其中一个示例如下所示:

L = [0, 1, 2, 0, 0, 2, 3, 1, 0, 10, 0, 2, 4, 5, 0, 0, 7, 8, 9, 0, ...]

singleData = []
sumofTwo = []
sumofThree = []
sumofFour = []
.
.

我希望能够根据求和操作中涉及的数字计数,将一个数据或两个或多个连续数据的总和分类到相应的列表中。因此,如果两个数字之间出现零,则不考虑它们的和

例如,如果我取上面的列表,1和2的总和将被添加到列表sumofTwo中。类似地,如果它是三个连续数字的总和,且不出现0,则该总和应在三个列表的总和中(2,3,1;2,4,5和7,8,9的总和)。如果一个数字出现在两个或多个0之间,那么它将被附加到singleData列表中(例如10)

考虑到列表(L)中可能存在随机连续数的总和,我如何实现这一点?例如,6或7或8或任何连续数字的总和

我只能将0和两个数字之和之间的一个数字分开。代码如下:

for i in range(len(l)):
     try:
         if i == 0:
             if l[i] == 0:
                 continue
             elif l[i] != 0 and l[i+1] == 0:
                 singleData.append(l[i])
             elif l[i] != 0 and l[i+1] != 0:
                 sumofTwo.append(l[i]+l[i+1])

         elif i == len(l)-1:
             if l[i] != 0 and l[i-1] == 0:
                 singleData.append(l[i])

         else:
             if l[i] != 0:
                 if l[i+1] == 0 and l[i-1] == 0:
                     singleData.append(l[i])
                 elif l[i+1] != 0:
                     sumofTwo.append(l[i]+l[i+1])
     except IndexError:
         print("Index out of range")
我意识到,我的代码只会在更多连续数和的情况下变得更加混乱,最终以错误告终


有人能帮我吗?提前感谢:)

我要做的第一件事是更好地组织我们的输出列表,这样就可以使用连续数字的数量以相同的方式访问每个列表。正如@daviewales所建议的,您可以使用列表作为值的字典来实现这一点,比如
sums={}
,这样
sums[1]
将与
singleData
相同,
sums[2]
sumofTwo
相同,等等。这样,您将避免大量的
,如果要知道您应该将数据放在什么列表中,您只需要使用
sums[nbOfValuesInSum]
之类的东西

其次,您可以编写一个函数来检测非零值序列。一种可能是一个函数,它接受一个列表和一个开始索引,并返回下一个“有趣”序列的开始和结束索引。它看起来是这样的:

def findNextSequence(l, start):
    while l[start] == 0:
        if start == len(l)-1:
            return None # there is no non-zero value left
        start+=1
    # when we exit the loop, start is the index of the first non-zero value
    end = start + 1
    while l[end] != 0:
        if end == len(l)-1:
            break
        end+=1
    # and now end is the index of the first zero value after the sequence
    return (start, end)
然后可以在循环中调用它,如下所示:

i = 0
while True:
    bounds = findNextSequence(l, i)
    if bounds is None:
        break # there is no non-zero value left
    seq = l[bounds[0]:bounds[1]] # get the start and end index of the sequence
    if len(seq) not in sums:
        sums[len(seq)] = []
    sums[len(seq)].append(sum(seq)) # see? No need to explicitly check len(seq) to know what list I want
    i = bounds[1] # get ready for the next iteration
    if i == len(l):
        break

注意:如果它是一个全局变量,则无需将
l
作为
findNextSequence
的参数传递。我要做的第一件事是更好地组织输出列表,以便可以使用连续数字的数量以相同的方式访问每个列表。正如@daviewales所建议的,您可以使用列表作为值的字典来实现这一点,比如
sums={}
,这样
sums[1]
将与
singleData
相同,
sums[2]
sumofTwo
相同,等等。这样,您将避免大量的
,如果要知道您应该将数据放在什么列表中,您只需要使用
sums[nbOfValuesInSum]
之类的东西

其次,您可以编写一个函数来检测非零值序列。一种可能是一个函数,它接受一个列表和一个开始索引,并返回下一个“有趣”序列的开始和结束索引。它看起来是这样的:

def findNextSequence(l, start):
    while l[start] == 0:
        if start == len(l)-1:
            return None # there is no non-zero value left
        start+=1
    # when we exit the loop, start is the index of the first non-zero value
    end = start + 1
    while l[end] != 0:
        if end == len(l)-1:
            break
        end+=1
    # and now end is the index of the first zero value after the sequence
    return (start, end)
然后可以在循环中调用它,如下所示:

i = 0
while True:
    bounds = findNextSequence(l, i)
    if bounds is None:
        break # there is no non-zero value left
    seq = l[bounds[0]:bounds[1]] # get the start and end index of the sequence
    if len(seq) not in sums:
        sums[len(seq)] = []
    sums[len(seq)].append(sum(seq)) # see? No need to explicitly check len(seq) to know what list I want
    i = bounds[1] # get ready for the next iteration
    if i == len(l):
        break

注意:如果是全局变量,则无需将
l
作为
findNextSequence
的参数传递,我建议使用字典存储结果:

L=[0,1,2,0,0,2,3,1,0,10,0,2,4,5,0,0,7,8,9,0]
连续_和={}#创建一个空字典
我还建议直接遍历列表,而不是使用
range(len(L)

对于L中的数字:
打印(数字)
然后,您可以创建一个计数器变量来检查当前序列的长度,并在达到零时重置计数器

L=[0,1,2,0,0,2,3,1,0,10,0,2,4,5,0,0,7,8,9,0]
连续_和={}#创建一个空字典
计数器=0
总和=0
对于L中的数字:
如果数字==0:#保存当前总和并重置计数器
#检查我们是否已经有了这样长度的序列。
#如果是这样的话,我们已经添加了一个列表,因此可以附加到它。
如果计数器连续求和:
连续求和[计数器]。追加(求和)
否则:#如果这是我们第一次有这种长度序列
#我们需要在字典中创建一个新的键值对。
#请注意,该值是一个包含“sum”的列表。
#确保使用列表,以便以后可以附加到列表中。
连续求和[计数器]=[求和]
#重置计数器和总和
计数器=0
总和=0
其他:#增量计数器
计数器+=1
总和+=数字
打印(连续求和)
请注意,此代码不会对字典键进行排序,因此长度为
1
的序列的总和可能不会出现在开头。但您可以使用
连续总和[1]
访问它

还请注意,此版本的代码还计算长度
0
的序列。我怀疑这不是您想要的,但我会让您找出解决方法

输出:

{0:[0,0,0],2:[3],3:[6,11,24],1:[10]}
编辑: 我特意尝试使用内置函数和数据类型来解决这个问题。但是如果你真的想变得更花哨,你可以使用

下面是使用
defaultdict
的替代版本:

从集合导入defaultdict
L=[0,1,2,0,0,2,3,1,0,10,0,2,4,5,0,0,7,8,9,0]
连续_sums=defaultdict(list)#创建一个list类型的空defaultdict
计数器=0
总和=0
对于L中的数字:
如果数字==0:#保存当前总和并重置计数器
#defaultdict的魔力:
#我们不需要检查密钥是否存在。
#如果它还不存在,defaultdict将自动
#一个空的列表供我们附加到!
连续求和[计数器]。追加(求和)