簡體   English   中英

在字典列表中合並相同鍵的值

[英]Merge values of same key, in list of dicts

我是python 2.7的新手,盡管在StackOverflow上進行了廣泛的搜索,但仍無法弄清以下內容:

我有一個listdict就是我wan't結合起來,當密鑰相同,並添加特定值(在本例中'price' )。

輸入:

[{'id1': 'a', 'price': '2', 'color': 'green'}, {'id1': 'b', 'price': '5', 'color': 'red'}, {'id1': 'a', 'price': '2', 'color': 'green'}] 

預期:

[{'id1': 'a', 'price': '4', 'color': 'green'}, {'id1': 'b', 'price': '5', 'color': 'red'}]

與編輯前的問題相同的想法。

>>> data = [{'id1': 'a', 'price': '2', 'color': 'green'},
...         {'id1': 'b', 'price': '5', 'color': 'red'},
...         {'id1': 'a', 'price': '2', 'color': 'green'}]

構造一個臨時字典並在其中累積值

>>> temp = {}
>>> for d in data:
...     if d['id1'] not in temp:
...         temp[d['id1']] = {}
...     temp_d = temp[d['id1']]
...     temp_d['price'] = temp_d.get('price', 0) + int(d['price'])
...     temp_d.setdefault('colors', set()).add(d['color'])
... 
>>> temp
{'a': {'colors': {'green'}, 'price': 4}, 'b': {'colors': {'red'}, 'price': 5}}

然后使用列表理解和字典理解,重建字典列表。

>>> [{'id1': k, 'price': v['price'], 'colors': v['colors']} for k, v in temp.items()]
[{'id1': 'a', 'colors': {'green'}, 'price': 4}, {'id1': 'b', 'colors': {'red'}, 'price': 5}]

>>> data = [{'id1': 'a', 'price': '2'}, {'id1': 'b', 'price': '5'},
...         {'id1': 'a', 'price': '2'}]

創建一個臨時字典,在其中我們可以根據價格ID累計價格總和,

>>> temp = {}
>>> for d in data:
...     temp[d['id1']] = temp.get(d['id1'], 0) + int(d['price'])
... 
>>> temp
{'a': 4, 'b': 5}

在這里,我們嘗試從temp獲取d['id1']的值,如果找不到,將返回0。 然后,我們從當前字典中添加price ,並將結果存儲在針對當前id1的temp中。

然后像這樣用列表理解和字典重構來重建字典列表

>>> [{'id1': k, 'price': temp[k]} for k in temp]
[{'price': 4, 'id1': 'a'}, {'price': 5, 'id1': 'b'}]

這不如@thefourtheye好,但似乎對我有用:

di = [{'id1': 'a', 'price': '2', 'color': 'green'}, {'id1': 'b', 'price': '5', 'color': 'red'}, {'id1': 'a', 'price': '2', 'color': 'green'}] 

# Make a dict to hold new values!
newvals = {}

for d in di:
    for key, value in d.iteritems():
        if value.isdigit():
            if value in newvals:
                newvals[value] += int(value)
            else:
                newvals[value] = int(value)
        else:
            if value not in newvals:
                newvals[value] = value

for d in di:
    for nkey, nvalue in d.iteritems():
        d[nkey] = newvals[nvalue]

# Make a unique list of dicts
print {v['id1']:v for v in di}.values()

>>>[{'color': 'green', 'price': 4, 'id1': 'a'}, {'color': 'red', 'price': 5, 'id1': 'b'}]

這對我有用:

import collections 
from functools import reduce

data = [{'id1': 'a', 'price': '2', 'color': 'green'},
        {'id1': 'b', 'price': '5', 'color': 'red'},
        {'id1': 'a', 'price': '2', 'color': 'green'},
        {'id1': 'c', 'price': '2', 'color': 'blue'},
        {'id1': 'b', 'price': '5', 'color': 'red'},
        {'id1': 'b', 'price': '5', 'color': 'red'},
        {'id1': 'd', 'price': '1', 'color': 'white'},
        {'id1': 'b', 'price': '10', 'color': 'red'},
        {'id1': 'd', 'price': '20', 'color': 'yellow'}
        ]

valores = [list(item.values()) for item in data]
valores=[[item[0],int(item[1]),item[2]] for item in valores]

dicc = collections.defaultdict(list)
for item in valores:
    dicc[item[0]].append(item[1])
res=list(dicc.items())
res_def=[(t[0],sum(t[1])) for t in res]

colors=[dicc['color'] for dicc in data for item in res_def if item[0] == dicc['id1'] ]          
colors_unicos=reduce(lambda l, x: l.append(x) or l if x not in l else l, colors, [])
for lista in res_def:
    lista.append(colors_unicos.pop(0))

data_resultado=[{'id1':lista[0],'price':lista[1],'color':lista[2]}for lista in res_def]

輸出為:[{'id1':'a','price':4,4,color':'green'},{'id1':'b','price':25,'color':'red '},{'id1':'c','price':2,2,'color':'blue'},{'id1':'d','price':1,'color':'white'} ,{'id1':'e','price':20,'color':'yellow'}]]

我設法像這樣壓縮代碼:

import itertools as it
from operator import itemgetter

grupos = it.groupby(sorted(data, key=itemgetter('id1')), key=itemgetter('id1'))
res = [{'id1': v, 'price': sum(int(dicc['price']) for dicc in diccs) } for v, diccs in 
grupos]
print(res)

輸出為:

[{'id1': 'a', 'price': 4}, {'id1': 'b', 'price': 25}, {'id1': 'c', 'price': 2}, {'id1': 'd', 'price': 1}, {'id1': 'e', 'price': 20}]

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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