簡體   English   中英

如果某些鍵相同,則添加字典的其他值

[英]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}] 

如果鍵name1name2具有相同的值,則添加val1val2

這是預期的 output:

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

在第一個字典和第二個字典中, name1都是a並且name2都是b ,所以我們添加它們的值。

我正在嘗試使用循環,但沒有得到任何結果。

您可以使用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']))

您可以迭代並使用中間字典,其中(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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM