Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/329.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/list/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 循环列表时的累积添加_Python_List_For Loop_Cumulative Sum - Fatal编程技术网

Python 循环列表时的累积添加

Python 循环列表时的累积添加,python,list,for-loop,cumulative-sum,Python,List,For Loop,Cumulative Sum,我有一个很大的列表,其中一个摘录如下: power = [ ['1234-43211', [5, 6, -4, 11, 22]], ['1234-783411', [43, -5, 0, 0, -1]], ['1234-537611', [3, 0, -5, -6, 0]], ['1567-345411', [4, 6, 8, 3, 3]], ['1567-998711', [1, 2, 1, -4, 5]] ] >>> [li

我有一个很大的列表,其中一个摘录如下:

power = [
    ['1234-43211', [5, 6, -4, 11, 22]], 
    ['1234-783411', [43, -5, 0, 0, -1]], 
    ['1234-537611', [3, 0, -5, -6, 0]], 
    ['1567-345411', [4, 6, 8, 3, 3]], 
    ['1567-998711', [1, 2, 1, -4, 5]]
]
>>> [list(islice(accumulate(col), 1, None)) for col in cols]
[[48, 51], [1, 1], [-4, -9], [11, 5], [21, 21]]
字符串中的第一个数字是重要的,也是我希望用来分隔加法的数字。i、 e.我只想将每个站点内的值累加(并返回每个单数累加),决不将两个不同站点的值累加

我的目标是迭代这个列表,为一个站点累计添加int值,返回每个添加值,然后在列表中检测到下一个站点时重新开始

预期结果:

new = [
    [48, 1, -4, 11, -21], 
    [ 51, 1, -9, 5, -21], '### End of '1234' ### '
    [5,  8, 9, -1, 8], '### End of 1567 ###'
] or something similar to this
我尝试了以下方法:

for i in range(len(power)-1):
    front_num_1 = power[i][0].split('-')[0]
    front_num_2 = power[i+1][0].split('-')[0]
    station = '%s' % (front_num_1)
    j = power[i][1]
    k = power[i+1][1]

    if front_num_1 == front_num_2:
        print [k + j for k, j in zip(j, k)]

    elif front_num_1 != front_num_2:
        print  '#####################################

    else:
        print 'END'

但是,此添加不是累积的,因此没有任何用处。

如果您将问题分解为更小的部分,则会有所帮助。我似乎明白,您想要1)根据某种标准拆分列表,然后2)获取每个子列表的累积和(将每个元素视为向量)

例如:

stationList = [
 ['1234-4321-1', [5, 6, -4, 11, 22]], 
 ['1234-7834-1', [43, -5, 0, 0, -1]], 
 ['1234-5376-1', [3, 0, -5, -6, 0]], 
 ['1567-3454-1', [4, 6, 8, 3, 3]], 
 ['1567-9987-1-', [1, 2, 1, -4, 5]]
]
变成:

{'1234-4321-1': [
    <5, 6, -4, 11, 22>, 
    <5, 6, -4, 11, 22> + <43, -5, 0, 0, -1>,
    <5, 6, -4, 11, 22> + <43, -5, 0, 0, -1> + <3, 0, -5, -6, 0>
 ], 
 '1567-3454-1': [
    <4, 6, 8, 3, 3>, 
    <4, 6, 8, 3, 3> + <1, 2, 1, -4, 5>
 ]
}
1) 要根据某些条件拆分列表,请使用itertools.groupby:。或者写一个生成器函数

getStation = lambda x: x[0].split('-')[0]
def groupby_station(inputList):
    return groupby(inputList, key=getStation)
2) 累积和可以写成生成函数。您可以使用
numpy
,也可以自己编写

def listAdd(*lists):
    """
        listAdd([1,2,3], [10,20,30]) -> [11,22,33]
        listAdd([1,2,3], []) -> [1,2,3]
    """
    return [sum(xs) for xs in zip_longest(*lists, fillvalue=0)]

def cumSum(lists):
    """
        cumSum([1,2],[10,20],[100,200]) -> ([1,2],[11,22],[111,222])
    """
    total = []
    for list in lists:
        total = listAdd(total, list)
        yield total
现在将两者结合起来:

{key:cumSum(*lists) for key,lists in groupby_station(inputList)}
请注意,我对累计金额的定义与你的略有不同;您可以修改
cumSum
函数以匹配您的定义。

来自itertools import groupby,islice
def累积(iterable):#在py 3中,使用itertools.ACCUMATE
''Python3的简化版本''
it=国际热核实验堆(iter)
总计=下一个(it)
总产量
对于其中的元素:
总数+=元素
总产量
功率=[
['1234-4321-1', [5, 6, -4, 11, 22]],
['1234-7834-1', [43, -5, 0, 0, -1]],
['1234-5376-1', [3, 0, -5, -6, 0]],
['1567-3454-1', [4, 6, 8, 3, 3]],
['1567-9987-1-', [1, 2, 1, -4, 5]]
]
组=((k,(表示站点的nums,表示g中的nums))
对于k,g-in
groupby(幂,λx:x[0]。分区('-')[0]))
新=[(站点,邮政编码(*(islice(累计(col),1,无)用于邮政编码中的col(*nums)))
对于站点,NUM分组]
打印新的
打印dict(新)#或作为无序的词典
输出

[('1234', [(48, 1, -4, 11, 21), (51, 1, -9, 5, 21)]), ('1567', [(5, 8, 9, -1, 8)])]
{'1234': [(48, 1, -4, 11, 21), (51, 1, -9, 5, 21)], '1567': [(5, 8, 9, -1, 8)]}
工作原理:

首先,使用
itertools.groupby
根据站点对列表进行分组

例如

是第一组。正如你所看到的,它是以矩阵的形式出现的

使用参数解包转换矩阵。它叫

zip([5, 6, -4, 11, 22], [43, -5, 0, 0, -1], [3, 0, -5, -6, 0])
这将创建列表:

cols = [(5, 43, 3), (6, -5, 0), (-4, 0, -5), (11, 0, -6), (22, -1, 0)]
然后在每个列上调用acculate,如下所示:

>>> [list(accumulate(col)) for col in cols]
[[5, 48, 51], [6, 1, 1], [-4, -4, -9], [11, 11, 5], [22, 21, 21]]
正如您可以看到的,这里每个列表中的第一个元素不是必需的,因此
islice
用于从索引
1
获取元素,直到结束(
None
)。下面是它的样子:

power = [
    ['1234-43211', [5, 6, -4, 11, 22]], 
    ['1234-783411', [43, -5, 0, 0, -1]], 
    ['1234-537611', [3, 0, -5, -6, 0]], 
    ['1567-345411', [4, 6, 8, 3, 3]], 
    ['1567-998711', [1, 2, 1, -4, 5]]
]
>>> [list(islice(accumulate(col), 1, None)) for col in cols]
[[48, 51], [1, 1], [-4, -9], [11, 5], [21, 21]]
现在我们只需要把这个移回去

>>> zip(*(islice(accumulate(col), 1, None) for col in cols))
[(48, 1, -4, 11, 21), (51, 1, -9, 5, 21)]

请以后使用pprint.pprint或手动格式化代码。另外,请在将来添加
python
标记。非常感谢。依我的拙见,基于“期望的结果”,不清楚你想做什么。编辑:啊,我明白了,你想把名单分开,然后做一个累加。我也不明白你的目标。而且我无法推断如何从
电源
生成
新的
。请更详细地描述您想要完成的内容。@user1532369我知道您有三个答案告诉您使用
groupby
。然而,他们都想当然地认为属于同一工作站的项目在
power
列表中聚集在一起。如果情况并非总是如此,他们的解决方案就会失败。首先使用与groupby使用相同的键排序
power
。@user1532369:sentinel/dummy值,正如您所建议的,被认为是糟糕的编程实践,因为它们使模块化特别困难。事实上,您提出的主要问题源于模块化不足,因此我要提醒您不要这样做。此输出是完美的,除非我需要插入一个标记,甚至站点编号,以便我知道哪些累积添加属于哪些站点,例如输出列表开头的“1234”(或末尾的第二个)以及“1567”列表中的第二个(或最后一个)元素,作为idicator。在我想要的结果中,我把它们作为“#########站号1234####”输入,但我意识到这可能不是一个注释,我的错。@user1532369我在那里给出了两个结构,dict和list,并以站号为键。@user1532369没问题:)我添加了一个解释。哇,这很全面。我非常感谢您抽出时间,这是一个高质量的回答和解释!最后一件事,如果我想省去每个站点的最后一个总和,我会用什么来代替“无”?@user1532369在这种情况下,我会将它转换成一个列表,而不使用
islice
so
list(accumulate(col))[1:-1]
。我想这就是你的意思,而不是
None