nvergos nvergos - 1 year ago 47
Python Question

merge python dictionaries when a key has a certain value

I have a list of python dictionaries, looking like this:

[{key1: value1, key2: array1}, {key1: value2, key2: array2}, {key1: value3, key3: array3},...]

In my case, some of these dictionaries have the same value for key1, for example, value1 = value3. How can I end up getting an array of dictionaries that will look like this?

[{key1: value1, key2: array1+array3}, {key1: value2, key2: array2},...]

where "array1+array3" is a single array with appended elements of the original array1 and array3 arrays?

edit: this is not merging by key; each dictionary in the array has strictly the same structure: {key1: "some_string", key2: [an array]} - my problem is that I wish to "merge" them on the "some_string", so the [an array], the value of key2, will be concatenated with arrays from other dictionaries in the list that have the same "some_string" as value of key1.

Answer Source

The best way to do what you want is to re-structure your data, at least temporarily. If you were to use a dictionary that mapped from value to array (without the fixed keys), you could put all the data into a single place and efficiently detect when duplicate values occur so that you can merge the values together. If need be, you can turn the single dictionary back into a list of smaller dictionaries afterwards.

Try something like this:

merged = {}
for d in list_of_dicts:
    if d["key1"] not in d:
        merged[d["key1"]] = d["key2"]
        merged[d["key1"]] += d["key2"]

# if necessary, put back into a list of dicts:
merged_list = [{"key1": k, "key2": v} for k, v in merged.items()]

The order of the list at the end will be arbitrary. If you want to preserve the order of the dicts in the original list, you could use an OrderedDict for merged.