这是我的输入。我有一个字典列表:
[{'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
。
这是预期的输出:
[{'name1':'a', 'name2':'b','val1':25,'val2':45},
{'name1':'r', 'name2':'s','val1':30,'val2':20}]
在第一个字典和第二个字典中,name1
和a
均为name2
,所以我们将它们的值相加。
我正在尝试循环,但没有到达任何地方。
答案 0 :(得分:2)
您可以使用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']))
答案 1 :(得分:1)
您可以迭代并使用中间字典,其中(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}]
答案 2 :(得分:1)
通过熊猫运行它,这对这类东西非常有用。 (是的,这 可能会折叠成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}]
答案 3 :(得分:-1)
我建议您发布尝试过的代码,然后寻求帮助,以便其他人可以通过建议一些更改来提供帮助。 但是这样的事情可以帮助您,
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的总和。