[英]Merge values of same key, in list of dicts
我是python 2.7的新手,盡管在StackOverflow上進行了廣泛的搜索,但仍無法弄清以下內容:
我有一個list
的dict
就是我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.