使用公共键/值对Python字典列表中的值进行求和
抱歉如果这个问题已经被问过了。我是个新手,虽然看了几个和我问题相似的问答,但还是找不到合适的解决办法。我试过用Counter,但不知道怎么保持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值不变,但把字典中的其他值相加。所以所有对应ID为1的值应该加在一起。
例如这个:
list = [{'ID':1, 'T2':10, 'T3':20}, {'ID':1, 'T2':5, 'T3':10}]
变成这个:
newlist = [{'ID':1, 'T2':15, 'T3':30}]
希望这能帮到你。
4 个回答
0
如果我理解得没错,这段话的意思是,我们要根据'ID'这个键的值来分组,然后对每个组内对应的键的值进行求和。如果这些键是一致的,也就是说第一个字典里的所有键在后面的字典里都能找到,那么可以用下面的代码来解决这个问题:
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]
如果我们的目标是对键进行求和,但这些键在不同的字典之间不一定能匹配,那么可以使用下面的代码:
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)
输出结果:
{'T1': 6, 'T2': 35, 'T3': 50, 'T4': 10}
1
我希望这能帮到你:
>>> 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}]
1
如果我理解你的需求没错的话,这里有一个解决方案:
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}]
4
很难理解你想要的结果是什么,尤其是你给出的输入。请提供一个具体的例子,说明你期望的正确输出是什么。
我怀疑你想要的结果是这个?
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}