【问题标题】:How to sum elements of nested list based on condition?如何根据条件对嵌套列表的元素求和?
【发布时间】:2020-07-13 06:02:34
【问题描述】:

我有一个如下所示的嵌套列表,我正在尝试将与第 2 列中的相同值相关的第 1 列的值相加,并添加 一个带有总和的新子列表和另一个带有“Total”的子列表。

a = [
        ['45', '00128'], 
        ['88', '00128'], 
        ['87', '00128'], 
        ['50', '88292'], 
        ['69', '88292'], 
        ['70', '72415'], 
        ['93', '72415'], 
        ['79', '72415']
    ]

我当前的代码如下所示,我想这将在列表a 上运行某些内容,但不会更改a 中的任何内容。

for sl in a:
    x = sl[1]; c0=0
    if (sl[1] == x):
        c0 = c0 + int(sl[0])
    else:
        a.insert(a.index(sl)+1,[c0,''])
        a.insert(a.index(sl)+2,['Total',''])        

我要找的输出是这样的:

b = [
        ['45',  '00128'], 
        ['88',  '00128'], 
        ['87',  '00128'],
        ['220', ''],      # This is 45 + 88 + 87
        ['Total', ''],
        ['50', '88292'], 
        ['69', '88292'], 
        ['119', ''],      # This is 50 + 69
        ['Total', ''],      
        ['70', '72415'], 
        ['93', '72415'], 
        ['79', '72415'],
        ['242', ''],      # This is 70 + 93 + 79
        ['Total', '']       
    ]

如何做到这一点?谢谢

更新

输入列表有 4 列,如左侧一列,需要对 col1、col3 和 col4 求和才能得到右侧的一列。

a = [                              >>  b = [
        ['45', '00128', '2','4'],  >>          ['45',    '00128', '2',     '4'    ], 
        ['88', '00128', '1','3'],  >>          ['88',    '00128', '1',     '3'    ], 
        ['87', '00128', '4','0'],  >>          ['87',    '00128', '4',     '0'    ], 
        ['50', '88292', '1','1'],  >>          ['220',   ''     , '7',     '7'    ],
        ['69', '88292', '9','5'],  >>          ['Total', '',      'Total', 'Total'],
        ['70', '72415', '8','9'],  >>          ['50',    '88292', '1',     '1'    ], 
        ['93', '72415', '3','2'],  >>          ['69',    '88292', '9',     '5'    ],
        ['79', '72415', '5','7']   >>          ['119',   '',      '10',    '6'    ],
    ]                              >>          ['Total', '',      'Total', 'Total'],
                                   >>          ['70',    '72415', '8',     '9'    ], 
                                   >>          ['93',    '72415', '3',     '2'    ], 
                                   >>          ['79',    '72415', '5',     '7'    ],
                                   >>          ['242',   '',      '16',    '18'   ],
                                   >>          ['Total', '',      'Total', 'Total'],
                                   >>       ]

【问题讨论】:

    标签: python-3.x nested-lists


    【解决方案1】:

    使用itertools.groupby

    from itertools import groupby
    
    result = []
    for m,n in groupby(a, lambda x: x[1]):
        n = list(n)
        result.extend(n + [[sum(int(i) for i, _ in n), ""]])
    print(result)
    

    输出:

    [['45', '00128'],
     ['88', '00128'],
     ['87', '00128'],
     [220, ''],
     ['50', '88292'],
     ['69', '88292'],
     [119, ''],
     ['70', '72415'],
     ['93', '72415'],
     ['79', '72415'],
     [242, '']]
    

    根据评论编辑

    for m,n in groupby(a, lambda x: x[1]):
        n = list(n)
        val_1, val_2, val_3 = 0, 0, 0
        for i in n:
            val_1 += int(i[0])
            #val_2, val_3....
        result.extend(n + [[val_1, ""]])
    

    如果你可以使用numpy,那么轴0的和就更简单了

    例如:

    for m,n in groupby(a, lambda x: x[1]):
        n = np.array(list(n), dtype=int)
        print(np.delete(np.sum(n, axis=0), 1))
    

    np.delete --> Delete element in index 1
    np.sum with axis=0 --> sum element in column. 
    

    【讨论】:

    • 您好,感谢您的帮助。我的实际输入列表有更多列。不用说,col1 和 col2 是一样的,list 有 4 列。如果我想对 col1、col3 和 col4 求和。如何更改result.extend 中的参数?
    • 对不起,我不明白...您要删除重复项吗?如果是这样,请使用set,然后使用sum
    • 我在原始帖子中添加了一个更新,其中包含一个包含 4 列的示例输入列表以及如果我需要对 col1、col3 和 col4 求和时的预期输出。在那种情况下,如何更改命令result.extend(n + [[sum(int(i) for i, _ in n), ""]])
    • 非常好,效果很好。感谢您的帮助。
    【解决方案2】:

    您好像从电子表格中导入了数据?一个非常干净的方法是使用 pandas 库,并让它为您处理数据:

    a = [
            ['45', '00128'], 
            ['88', '00128'], 
            ['87', '00128'], 
            ['50', '88292'], 
            ['69', '88292'], 
            ['70', '72415'], 
            ['93', '72415'], 
            ['79', '72415']
    ]
    
    # Import the library
    import pandas as pd
    
    # Put data into a pandas DataFrame and set column names
    df = pd.DataFrame(a, columns=['value', 'category'])
    
    # Change `value` column to integers
    df['value'] = df['value'].astype(int)
    
    # Group by the `category` column and sum
    sum_df = df.groupby('category').sum()
    
    # Show answer
    print(sum_df)
    

    应该打印出以下内容:

              value
    category
    00128       220
    72415       242
    88292       119
    

    【讨论】:

    • 感谢您的回答。我看到您通过该过程得到了总和,但我不清楚如何获得我正在寻找的输出列表。
    【解决方案3】:

    一种非常原始的方式。这只是为了知识目的。我会推荐 Rakesh 给出的答案

    from collections import defaultdict
        
    sums_dict = defaultdict(int)
    a = [
            ['45', '00128'],
            ['88', '00128'],
            ['87', '00128'],
            ['50', '88292'],
            ['69', '88292'],
            ['70', '72415'],
            ['93', '72415'],
            ['79', '72415']
        ]
    sums_dict = {v:sums_dict[v]+int(k) for k,v in a}
    
    for k in sums_dict:
        index = next((len(a) - i - 1 for i, lst in enumerate(reversed(a)) if k in lst), -1)
        a.insert(index, [str(sums_dict[k]),""])
        a.insert(index+2, ['Total', ''])
    
    print(a)
    

    输出:

    [['45', '00128'], ['88', '00128'], ['87', ''], ['87', '00128'], ['Total', ''], ['50', '88292'], ['69', ''], ['69', '88292'], ['Total', ''], ['70', '72415'], ['93', '72415'], ['79', ''], ['79', '72415'], ['Total', '']]
    

    【讨论】:

    • 感谢您的回答。我试过了,但这部分出现错误sums_dict = {v:d[v]+int(k) for k,v in a} ... >>> KeyError: '00128'
    猜你喜欢
    • 2017-04-25
    • 1970-01-01
    • 2017-02-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-01-25
    • 1970-01-01
    相关资源
    最近更新 更多