Merge values ​​of the same key in dicts list

I'm relatively new to python 2.7 and can't figure it out despite a widespread search in StackOverflow:

I have a list of dict I will not combine when the key is the same, and add certain values ​​(in the example 'price' ).

Input:

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

Expected:

 [{'id1': 'a', 'price': '4', 'color': 'green'}, {'id1': 'b', 'price': '5', 'color': 'red'}] 
+6
source share
5 answers

Same as your question before editing.

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

Create a temporary dictionary and copy the values ​​into it

 >>> 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}} 

Then, using list comprehension and dictionary comprehension, restore the list of dictionaries.

 >>> [{'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'}] 

Create a temporary dictionary in which we can sum the sum of prices against their identifiers,

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

Here we try to get the value d['id1'] from temp , and if it is not found, 0 will be returned. Then we add price from the current dictionary and save the result back to temp against the current id1.

Then restore the list of dictionaries using list comprehension and dictionary comprehension, e.g.

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

This is not as good as @thefourtheye, but it seems to work for me:

 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'}] 
0
source

Yo he tenido recientemente un problema semejante y llegado a una soluciΓ³n, pero tengo dudas sobre su eficiencia:

 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'} ] import collections valores = [list(item.values()) for item in data] tipos = [] precios = [] colores = [] for item in valores: tipos.append(item[0]) precios.append(int(item[1])) colores.append(item[2]) lista_tuplas = list(zip(tipos,precios,colores)) dicc = collections.defaultdict(list) for item in lista_tuplas: dicc[item[0]].append(item[1]) res = list(dicc.items()) res_def = [(t[0],sum(t[1])) for t in res] print(res_def) 

La salida es: [('a', 4), ('b', 25), ('c', 2), ('d', 21)]

Espero Sirva de Ayuda. Saludos

0
source

This works for me:

 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] 

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

0
source

I managed to compress the code as follows:

 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) 

output:

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

Source: https://habr.com/ru/post/988851/


All Articles