使用公共键/值对Python字典列表中的值求和

使用公共键/值对Python字典列表中的值求和,python,dictionary,sum,Python,Dictionary,Sum,如果已经有人问过这个问题,请道歉。我在这方面是个新手,但我已经看了一些其他的问题/答案,这些问题/答案看起来与我的类似,但找不到一个能起作用的。我尝试了计数器,但似乎不知道如何保留ID键/值 我试图使用公共键/值对Python字典中的值求和。例如: list = [ {'ID':1, 'T2':10, 'T3':20}, {'ID':2, 'T2':5, 'T3':0}, {'ID':1, 'T2':5, 'T3':10}, {'ID':2, 'T2':10, '

如果已经有人问过这个问题,请道歉。我在这方面是个新手,但我已经看了一些其他的问题/答案,这些问题/答案看起来与我的类似,但找不到一个能起作用的。我尝试了计数器,但似乎不知道如何保留ID键/值

我试图使用公共键/值对Python字典中的值求和。例如:

list = [
    {'ID':1, 'T2':10, 'T3':20},
    {'ID':2, 'T2':5, 'T3':0},
    {'ID':1, 'T2':5, 'T3':10},
    {'ID':2, 'T2':10, 'T3':30},
    {'ID':3, 'T2':5, 'T3':0}
]
但我需要这个:

newlist = [
    {'ID':1, 'T2':15, 'T3':30}, 
    {'ID':2, 'T2':15, 'T3':30}, 
    {'ID':3, 'T2':5, 'T3':0}
]
谢谢你的帮助

更新:


我借用了另一个答案并尝试了以下方法:

superdict = {}
for d in rows:
  for k, v in d.items():
      if superdict.get(k) is None:
          superdict[k] = []
      if superdict.get(k) is not None:
          superdict[k].append(v)    
但是,我没有继续得到一个新的组合/附加值列表,而是得到了如下内容:

'ID': ['3903', '3997', '3997', '3997', '3947', '4097', '3445', 
       '3997', '4107', '3997', '3445', '3997', '3997', '3997', 
       '3997', '3445', '3997', etc. etc.
更新2:

对不起,我的例子有点混乱。我要寻找的是一种保持ID值静态但在字典中添加其他值的方法。因此,与值为1的ID对应的中的所有值将相加

例如,这:

list = [{'ID':1, 'T2':10, 'T3':20}, {'ID':1, 'T2':5, 'T3':10}]
变成这样:

newlist = [{'ID':1, 'T2':15, 'T3':30}]

希望这能有所帮助。

如果我正确理解您的需求,这里有一个解决方案:

def sum_by_common_key(input_list, index_key='ID'):
    output_dict = {}
    for d in input_list:
        index = d[index_key]
        if index not in output_dict:
            output_dict[index] = {}
        for k, v in d.items():
            if k not in output_dict[index]:
                output_dict[index][k] = v
            elif k != index_key:
                output_dict[index][k] += v
    return output_dict.values()

l = [{'ID':1, 'T2':10, 'T3':20}, {'ID':2, 'T2':5, 'T3':0}, {'ID':1, 'T2':5, 'T3':10}, {'ID':2, 'T2':10, 'T3':30}, {'ID':3, 'T2':5, 'T3':0}]
print sum_by_common_key(l)

>>> [{'T2': 15, 'ID': 1, 'T3': 30}, {'T2': 15, 'ID': 2, 'T3': 30}, {'T2': 5, 'ID': 3, 'T3': 0}]
my_list = [{'ID':1, 'T2':10, 'T3':20},
           {'ID':2, 'T2':5, 'T3':0}, 
           {'ID':1, 'T2':5, 'T3':10}, 
           {'ID':2, 'T2':10, 'T3':30}, 
           {'ID':3, 'T2':5, 'T3':0}]


# prep keys
id_keys = set([ z['ID'] for z in my_list ])
sum_keys = [ z for z in my_list[0].keys() if z != 'ID' ]
print('ids to group by', id_keys)
print('keys to sum over', sum_keys)

# restructure the data
big = [ [z.pop('ID'), z] for z in my_list ]
print('[[group_key, {remaining dict],] :\n', big)

# initiate results accumulator
rez = {idd: dict.fromkeys(sum_keys, 0) for idd in id_keys }
print('empty accumulator', rez)

# two loops in list comprehension
[ rez[g[0]].update({k: rez[g[0]][k] + g[1][k]}) for k in sum_keys for g in big ]
print('result', rez)

很难理解给定输入的期望结果是什么。给出预期/正确输出的具体示例

我怀疑这就是你的目的

my_list = [{'ID':1, 'T2':10, 'T3':20},
           {'ID':2, 'T2':5, 'T3':0}, 
           {'ID':1, 'T2':5, 'T3':10}, 
           {'ID':2, 'T2':10, 'T3':30}, 
           {'ID':3, 'T2':5, 'T3':0}]

new_dictionary = {}
for dictionary in my_list:
    for key, value in dictionary.items():
        if new_dictionary.has_key(key):
            new_dictionary[key] = value + new_dictionary[key]
        else:
            new_dictionary[key] = value

#Output:
>>>new_dictionary
{'T2': 35, 'ID': 9, 'T3': 60}

我希望这将有助于您:

>>> from collections import Counter
>>> old_list=[{'ID':1, 'T2':10, 'T3':20}, {'ID':2, 'T2':5, 'T3':0}, {'ID':1, 'T2':5, 'T3':10}, {'ID':2, 'T2':10, 'T3':30}, {'ID':3, 'T2':5, 'T':0}]
>>> new_list=[]
>>> for i,a in enumerate(old_list):
...     z=0
...     for b in old_list[i+1:]:
...        if a['ID']==b['ID']:
...           new_list.append(dict(Counter(a)+Counter(b)))
...           new_list[-1]['ID']=a['ID']
...           temp=old_list.pop(old_list.index(b))
...           z=1
...     if not z:
...        new_list.append(a)
... 
>>> new_list
[{'T2': 15, 'ID': 1, 'T3': 30}, {'T2': 15, 'ID': 2, 'T3': 30}, {'T2': 5, 'ID': 3, 'T3': 0}]

如果正确地解释了这一点,目标是按键“ID”的值分组,然后对组中相应键的值求和。如果密钥是一致的,即第一个dict中的所有密钥都保证在后面的dict中显示,则有一个解决方案:

def sum_by_common_key(input_list, index_key='ID'):
    output_dict = {}
    for d in input_list:
        index = d[index_key]
        if index not in output_dict:
            output_dict[index] = {}
        for k, v in d.items():
            if k not in output_dict[index]:
                output_dict[index][k] = v
            elif k != index_key:
                output_dict[index][k] += v
    return output_dict.values()

l = [{'ID':1, 'T2':10, 'T3':20}, {'ID':2, 'T2':5, 'T3':0}, {'ID':1, 'T2':5, 'T3':10}, {'ID':2, 'T2':10, 'T3':30}, {'ID':3, 'T2':5, 'T3':0}]
print sum_by_common_key(l)

>>> [{'T2': 15, 'ID': 1, 'T3': 30}, {'T2': 15, 'ID': 2, 'T3': 30}, {'T2': 5, 'ID': 3, 'T3': 0}]
my_list = [{'ID':1, 'T2':10, 'T3':20},
           {'ID':2, 'T2':5, 'T3':0}, 
           {'ID':1, 'T2':5, 'T3':10}, 
           {'ID':2, 'T2':10, 'T3':30}, 
           {'ID':3, 'T2':5, 'T3':0}]


# prep keys
id_keys = set([ z['ID'] for z in my_list ])
sum_keys = [ z for z in my_list[0].keys() if z != 'ID' ]
print('ids to group by', id_keys)
print('keys to sum over', sum_keys)

# restructure the data
big = [ [z.pop('ID'), z] for z in my_list ]
print('[[group_key, {remaining dict],] :\n', big)

# initiate results accumulator
rez = {idd: dict.fromkeys(sum_keys, 0) for idd in id_keys }
print('empty accumulator', rez)

# two loops in list comprehension
[ rez[g[0]].update({k: rez[g[0]][k] + g[1][k]}) for k in sum_keys for g in big ]
print('result', rez)
输出:

ids to group by {1, 2, 3}
keys to sum over ['T2', 'T3']
[[group_key, {remaining dict],] :
 [[1, {'T2': 10, 'T3': 20}], [2, {'T2': 5, 'T3': 0}], [1, {'T2': 5, 'T3': 10}], [2, {'T2': 10, 'T3': 30}], [3, {'T2': 5, 'T3': 0}]]
empty accumulator {1: {'T2': 0, 'T3': 0}, 2: {'T2': 0, 'T3': 0}, 3: {'T2': 0, 'T3': 0}}
result {1: {'T2': 15, 'T3': 30}, 2: {'T2': 15, 'T3': 30}, 3: {'T2': 5, 'T3': 0}}
[Finished in 0.2s]
{'T1': 6, 'T2': 35, 'T3': 50, 'T4': 10}

如果目标是在多个键上求和,并且不能保证键从一个dict匹配到下一个dict,请使用以下代码:

my_list = [{'T1':1, 'T2':10, 'T3':20},
           {'T1':2, 'T2':5 , 'T3':0}, 
           {        'T2':5 ,       }, 
           {        'T2':10, 'T3':30, 'T4': 7}, 
           {'T1':3, 'T2':5 , 'T3':0 , 'T4': 3}]

rez = {}
for dic in my_list:
    for key in dic.keys():
        rez[key]=rez.setdefault(key, 0) + dic[key]

print(rez)
输出:

ids to group by {1, 2, 3}
keys to sum over ['T2', 'T3']
[[group_key, {remaining dict],] :
 [[1, {'T2': 10, 'T3': 20}], [2, {'T2': 5, 'T3': 0}], [1, {'T2': 5, 'T3': 10}], [2, {'T2': 10, 'T3': 30}], [3, {'T2': 5, 'T3': 0}]]
empty accumulator {1: {'T2': 0, 'T3': 0}, 2: {'T2': 0, 'T3': 0}, 3: {'T2': 0, 'T3': 0}}
result {1: {'T2': 15, 'T3': 30}, 2: {'T2': 15, 'T3': 30}, 3: {'T2': 5, 'T3': 0}}
[Finished in 0.2s]
{'T1': 6, 'T2': 35, 'T3': 50, 'T4': 10}

您的逻辑中发生了什么?不清楚list和newlist之间发生了什么。请你澄清一下,我借用了另一个答案: