Merge Values for Same Key

Combine values of same keys in a list of dicts

bar = {
k: [d.get(k) for d in foo]
for k in set().union(*foo)
}

Things to google:

  • python list comprehension
  • python dict comprehension
  • python star
  • python dict get
  • python set union

How to merge dicts, collecting values from matching keys?

assuming all keys are always present in all dicts:

ds = [d1, d2]
d = {}
for k in d1.iterkeys():
d[k] = tuple(d[k] for d in ds)

Note: In Python 3.x use below code:

ds = [d1, d2]
d = {}
for k in d1.keys():
d[k] = tuple(d[k] for d in ds)

and if the dic contain numpy arrays:

ds = [d1, d2]
d = {}
for k in d1.keys():
d[k] = np.concatenate(list(d[k] for d in ds))

How to merge items based on the same key/value in a python list

So, you just want the standard dictionary grouping idiom based on the key you described:

>>> data = [{
... "category": "Nace2008",
... "code": "01110",
... "NL": "Teelt van granen (m.u.v. rijst), peulgewassen en oliehoudende zaden"
... },
... {
... "category": "Nace2008",
... "code": "01110",
... "FR": "Culture de c\u00e9r\u00e9ales (\u00e0 l'exception du riz), de l\u00e9gumineuses et de graines ol\u00e9agineuses"
... },
... {
... "category": "Nace2008",
... "code": "01120",
... "FR": "Culture du riz"
... },
... {
... "category": "Nace2008",
... "code": "01120",
... "NL": "Teelt van rijst"
... }]

So create an empty dictionary, group by the key:

>>> result = {}
>>> for d in data:
... key = d['category'], d['code']
... result.setdefault(key, {}).update(d)
...

Note, the .update just merges whatever is there naively. If you would have duplicate keys in subsequent records, then it would take the last one. If they are all unique, it shouldn't be a problem. And the results:

>>> from pprint import pprint
>>> pprint(result)
{('Nace2008', '01110'): {'FR': "Culture de céréales (à l'exception du riz), de "
'légumineuses et de graines oléagineuses',
'NL': 'Teelt van granen (m.u.v. rijst), peulgewassen '
'en oliehoudende zaden',
'category': 'Nace2008',
'code': '01110'},
('Nace2008', '01120'): {'FR': 'Culture du riz',
'NL': 'Teelt van rijst',
'category': 'Nace2008',
'code': '01120'}}

Then you can extract the values of that dictionary if you want just that:

>>> pprint(list(result.values()))
[{'FR': "Culture de céréales (à l'exception du riz), de légumineuses et de "
'graines oléagineuses',
'NL': 'Teelt van granen (m.u.v. rijst), peulgewassen en oliehoudende zaden',
'category': 'Nace2008',
'code': '01110'},
{'FR': 'Culture du riz',
'NL': 'Teelt van rijst',
'category': 'Nace2008',
'code': '01120'}]

Note, the grouping idiom can be cleaned up a bit using defaultdict (some people find .setdefault confusing):

from collections import defaultdict
result = defaultdict(dict)
for d in data:
key = d['category'], d['code']
result[key].update(d)

Both are the same as:

result = {}
for d in data:
key = d['category'], d['code']
if key not in result:
result[key] = {}
result[key].update(d)

Merge values of same keys in JS

You can use Array.reduce(...) on your data and then loop over each object to add them to the reduced value accordingly.

Also, your original array needs some "quotes" on the object keys, otherwise it won't run:

const DATA = [
{"-a": '-ess. (form feminine singular nouns.)'},
{"-a": '(form the feminine singular adjectives.)'},
{"-a": '(form the second-person singular.)'},
{"-aba": 'first-person singular'},
{"-aba": 'third-person singular'},
];

const merge = (data) => {
// reduce the array down to a single object
return data.reduce((acc, curr) => {
// loop over the entries of each object
Object.entries(curr).forEach(([key, value]) => {
// if this key already exists, append to it with \n
if(acc[key] != null) {
acc[key] += `\n${value}`;

// else, just add it as is
} else {
acc[key] = value;
}
});

return acc;
}, {});
}

console.log(merge(DATA));

Merge multiple values for same key to one dict/json (Pandas, Python, Dataframe)?

After you groupby(['id', 'key']) and agg(list), you can group by the first level of the index and for each group thereof, use droplevel + to_dict:

new_df = df.groupby(['id', 'key']).agg(list).groupby(level=0).apply(lambda x: x['value'].droplevel(0).to_dict()).reset_index(name='value')

Output:

>>> new_df
id value
0 1 {'a': ['kkk', 'aaa'], 'b': ['5']}
1 2 {'a': ['kkk'], 'b': ['8']}

Or, simpler:

new_df = df.groupby('id').apply(lambda x: x.groupby('key')['value'].agg(list).to_dict())

How to merge keys of dictionary which have the same value?

I am not sure why you would need such a data structure, you can probably find a better solution to your problem. However, just for the sake of answering your question, here is a possible solution:

dic1 = {'A':'B', 'C':'D'}
dic2 = {'D':'B', 'E':'F'}

key_list = list(dic2.keys())
val_list = list(dic2.values())

r = {}
for k,v in dic1.items():
if v in val_list:
i = val_list.index(v) #get index at value
k2 = key_list[i] #use index to retrive the key at value
r[(k, k2)] = v #make the dict entry
else:
r[k] = v

val_list = list(r.values()) #get all the values already processed
for k,v in dic2.items():
if v not in val_list: #if missing value
r[k] = v #add new entry

print(r)

output:

{('A', 'D'): 'B', 'C': 'D', 'E': 'F'}

You can't assign a list as a key in a python dictionary since the key must be hashable and a list is not an ashable object, so I have used a tuple instead.

Javascript: How to merge two objects and sum the values of the same key?

Using Array#reduce and Object#entries:

const 
map1 = { "a": 10, "b": 6 },
map2 = { "a": 10, "b": 6, "c": 7, "d": 8 };

// iterate over map2 entries with acc set to map1 at start
const merged = Object.entries(map2).reduce((acc, [key, value]) =>
// if key is already in map1, add the values, otherwise, create new pair
({ ...acc, [key]: (acc[key] || 0) + value })
, { ...map1 });

console.log(merged);

Merge multiple dicts with same key-value pair to one dict python

This is a perfect scenario to see the power of itertools.groupby
Note that I have assumed haps, state and ads will be present in all dictionaries, and will be similar in repetitions

from itertools import groupby

field_to_be_check = "state"
merger = ["city", "ads"]
merge_name = ["cities", "my_ads"]

data = [
{'haps': 'hap0', 'state': 'tamil nadu', 'ads': 'ad1', 'city': 'tirunelveli'},
{'haps': 'hap0', 'state': 'tamil nadu', 'ads': 'ad4', 'city': 'nagerkoil'},
{'haps': 'hap0', 'state': 'tamil nadu', 'ads': 'ad1', 'city': 'tuticorin'},
{'haps': 'hap0', 'state': 'tamil nadu', 'ads': 'ad1', 'city': 'madurai'},
{'haps': 'hap0', 'state': 'tamil nadu', 'ads': 'ad1', 'city': 'chennai'},
{'haps': 'hap1', 'state': 'kerala', 'ads': 'ad2', 'city': 'palakad'},
{'haps': 'hap1', 'state': 'kerala', 'ads': 'ad2', 'city': 'guruvayor'},
{'haps': 'hap1', 'state': 'kerala', 'ads': 'ad2', 'city': 'kolikodu'},
{'haps': 'hap1', 'state': 'kerala', 'ads': 'ad2', 'city': 'kottayam'},
{'haps': 'hap1', 'state': 'kerala', 'ads': 'ad2', 'city': 'idukki'},
{'haps': 'hap2', 'state': 'mumbai', 'ads': 'ad3', 'city': 'Akola'},
{'haps': 'hap2', 'state': 'mumbai', 'ads': 'ad3', 'city': 'Washim'},
{'haps': 'hap2', 'state': 'mumbai', 'ads': 'ad3', 'city': 'Jalna'},
{'haps': 'hap2', 'state': 'mumbai', 'ads': 'ad3', 'city': 'Nanded'},
{'haps': 'hap2', 'state': 'mumbai', 'ads': 'ad3', 'city': 'Latur'}
]

#Function to make the merger lists
def process_group(group, merger_item):

item_set = set()
item_list = []
for item in group:
item_set.add(item[merger_item])

for item in item_set:
item_list.append({merger_item: item})

return item_list

#Group on haps, state and ads
grp = groupby(data,key=lambda x:(x[field_to_be_check]))
result = []

#Iterate through the group and build your result list
for model, group in grp:
cities_dict = {}

cities_dict[field_to_be_check] = model

group_list = list(group)

#Make the list for merger fields
for idx, name in enumerate(merger):
cities_dict[merge_name[idx]] = process_group(group_list, name)

result.append(cities_dict)

print(result)

The output will look like

[{'state': 'tamil nadu', 
'cities': [{'city': 'nagerkoil'}, {'city': 'tuticorin'}, {'city': 'chennai'}, {'city': 'madurai'}, {'city': 'tirunelveli'}],
'my_ads': [{'ads': 'ad4'}, {'ads': 'ad1'}]},
{'state': 'kerala',
'cities': [{'city': 'guruvayor'}, {'city': 'idukki'}, {'city': 'kottayam'}, {'city': 'palakad'}, {'city': 'kolikodu'}],
'my_ads': [{'ads': 'ad2'}]},
{'state': 'mumbai',
'cities': [{'city': 'Jalna'}, {'city': 'Nanded'}, {'city': 'Washim'}, {'city': 'Latur'}, {'city': 'Akola'}],
'my_ads': [{'ads': 'ad3'}]}]

Merge values of same key, in list of dicts

Same idea as your question before the edit.

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

Construct a temporary dictionary and accumulate values in 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, reconstruct 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 where we can accummulate the sum of prices against their ids,

>>> 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 of d['id1'] from temp and if it is not found, 0 will be returned. We then add the price from the current dictionary and store the result back in the temp against the current id1.

Then reconstruct the list of dictionaries, with list comprehension and dictionary comprehension, like this

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

merge dicts that have the same value for specific key

If lst is list from your question, you can do:

out = {}
for l in lst:
for d in l:
out.setdefault(d["tag"], {}).update(d)

print(list(out.values()))

Prints:

[
{"tag": "#2C00L02RU", "stamina": 233, "health": 200, "fame": 4, "moves": 4},
{"tag": "#8YG8RJV90", "stamina": 20, "health": 40, "fame": 2, "moves": 0},
{"tag": "#LQV2JCPR", "stamina": 154, "health": 100, "fame": 1, "moves": 6},
{"tag": "#9JQLPGLJJ", "stamina": 134, "health": 240, "fame": 3, "moves": 8},
]


Related Topics



Leave a reply



Submit