[英]Add the other values of a dictionary if certain keys are the same
這是我的輸入。 我有一個字典列表:
[{'name1':'a', 'name2':'b','val1':10,'val2':20},
{'name1':'a', 'name2':'b','val1':15,'val2':25},
{'name1':'r', 'name2':'s','val1':30,'val2':20}]
如果鍵name1
和name2
具有相同的值,則添加val1
和val2
。
這是預期的 output:
[{'name1':'a', 'name2':'b','val1':25,'val2':45},
{'name1':'r', 'name2':'s','val1':30,'val2':20}]
在第一個字典和第二個字典中, name1
都是a
並且name2
都是b
,所以我們添加它們的值。
我正在嘗試使用循環,但沒有得到任何結果。
您可以使用collections.Counter
和itertools.groupby
:
>>> dicts = [{'name1':'a', 'name2':'b','val1':10,'val2':20},
{'name1':'a', 'name2':'b','val1':15,'val2':25},
{'name1':'r', 'name2':'s','val1':30,'val2':20}]
>>> new_dicts = []
>>> for k, groups in groupby(dicts, lambda d: (d.pop('name1'), d.pop('name2'))):
new_d = {
'name1': k[0],
'name2': k[1],
**sum([Counter(g) for g in groups], Counter())
}
new_dicts.append(new_d)
>>> new_dicts
[{'name1': 'a', 'name2': 'b', 'val1': 25, 'val2': 45},
{'name1': 'r', 'name2': 's', 'val1': 30, 'val2': 20}]
另一方面,如果您使用pandas
:
>>> pd.DataFrame(dicts).groupby(['name1', 'name2']).sum().reset_index().to_dict('r')
[{'name1': 'a', 'name2': 'b', 'val1': 25, 'val2': 45},
{'name1': 'r', 'name2': 's', 'val1': 30, 'val2': 20}]
如果您想在沒有模塊的情況下執行此操作,可以嘗試:
>>> new_dicts = []
>>> for d in dicts:
if not new_dicts:
new_dicts.append(d)
else:
last_dict = new_dicts[-1]
if (last_dict['name1'], last_dict['name2']) == (d['name1'], d['name2']):
last_dict['val1'] += d['val1']
last_dict['val2'] += d['val2']
else:
new_dicts.append(d)
>>> new_dicts
[{'name1': 'a', 'name2': 'b', 'val1': 25, 'val2': 45},
{'name1': 'r', 'name2': 's', 'val1': 30, 'val2': 20}]
注意:
第一個和第三個解決方案假設您的列表已排序,即相同的name1
name2
條目將連續出現,如果不是這種情況,您可以在開頭添加這一行:
>>> dicts = sorted(dicts, key=lambda x: (x['name1'], x['name2']))
您可以迭代並使用中間字典,其中(name1, name2)
是實現線性時間復雜度的關鍵。
>>> for d in l:
... name1, name2, val1, val2 = d['name1'], d['name2'], d['val1'], d['val2']
... if (name1, name2) in res:
... res[(name1, name2)] = res[(name1, name2)][0] + val1, res[(name1, name2)][1] + val2
... else:
... res[(name1, name2)] = (val1, val2)
...
>>> res
{('a', 'b'): (25, 45), ('r', 's'): (30, 20)}
>>> output = [{'name1': k[0], 'name2': k[1], 'val1': v[0], 'val2': v[1]} for k,v in res.items()]
>>> output
[{'name1': 'a', 'name2': 'b', 'val1': 25, 'val2': 45}, {'name1': 'r', 'name2': 's', 'val1': 30, 'val2': 20}]
通過 pandas 運行它,它非常擅長這類東西。 (是的,這可能會被折疊成 1 或 2 個鏈式語句。:
In [37]: a
Out[37]:
[{'name1': 'a', 'name2': 'b', 'val1': 10, 'val2': 20},
{'name1': 'a', 'name2': 'b', 'val1': 15, 'val2': 25},
{'name1': 'r', 'name2': 's', 'val1': 30, 'val2': 20}]
In [38]: df = pd.DataFrame(a)
In [39]: df
Out[39]:
name1 name2 val1 val2
0 a b 10 20
1 a b 15 25
2 r s 30 20
In [40]: grouped_sum = df.groupby(['name1', 'name2']).sum()
In [41]: grouped_sum
Out[41]:
val1 val2
name1 name2
a b 25 45
r s 30 20
In [42]: grouped_sum.reset_index(inplace=True)
In [43]: data = grouped_sum.to_dict('records')
In [44]: data
Out[44]:
[{'name1': 'a', 'name2': 'b', 'val1': 25, 'val2': 45},
{'name1': 'r', 'name2': 's', 'val1': 30, 'val2': 20}]
我建議您發布您嘗試過的代碼,然后尋求幫助,以便其他人可以通過提出一些更改來提供幫助。 但是這樣的事情可以幫助你,
di = [{'name1': 'a', 'name2': 'a', 'val1': 10, 'val2': 20},
{'name1': 'a', 'name2': 'b', 'val1': 15, 'val2': 25},
{'name1': 'r', 'name2': 's', 'val1': 30, 'val2': 20}]
for i in di:
if i['name1'] == i['name2']:
print("sum:", i['val1']+i['val2'])
如果 name1 和 name2 相等,它會打印 val1 和 val2 的總和。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.