如果某些键相同,则添加字典的其他值

时间:2020-08-11 14:19:25

标签: python python-3.x

这是我的输入。我有一个字典列表:

[{'name1':'a', 'name2':'b','val1':10,'val2':20},
 {'name1':'a', 'name2':'b','val1':15,'val2':25},
 {'name1':'r', 'name2':'s','val1':30,'val2':20}] 

如果键name1name2的值相同,则添加val1val2

这是预期的输出:

[{'name1':'a', 'name2':'b','val1':25,'val2':45},
 {'name1':'r', 'name2':'s','val1':30,'val2':20}] 

在第一个字典和第二个字典中,name1a均为name2,所以我们将它们的值相加。

我正在尝试循环,但没有到达任何地方。

4 个答案:

答案 0 :(得分:2)

您可以使用collections.Counteritertools.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的总和。