Combining dictionary value lists in python

I am trying to combine three dictionaries, all of which have the same keys, as well as lists of values ​​or single values.

one={'a': [1, 2], 'c': [5, 6], 'b': [3, 4]} two={'a': [2.4, 3.4], 'c': [5.6, 7.6], 'b': [3.5, 4.5]} three={'a': 1.2, 'c': 3.4, 'b': 2.3} 

I need all the elements in the values ​​to be added to the same list.

 result={'a': [1, 2, 2.4, 3.4, 1.2], 'c': [5, 6, 5.6, 7.6, 2.3], 'b': [3, 4, 3.5, 4.5, 3.4]} 

I tried a few things, but most put the values ​​in nested lists. For instance.

 out=dict((k, [one[k], two.get(k), three.get(k)]) for k in one) {'a': [[1, 2], [2.4, 3.4], 1.2], 'c': [[5, 6], [5.6, 7.6], 3.4], 'b': [[3, 4], [3.5, 4.5], 2.3]} 

I tried updating it by doing the following:

 out.update((k, [x for x in v]) for k,v in out.iteritems()) 

but the results were exactly the same. I tried just adding lists, but since the third dictionary has only float, I could not do this.

 check=dict((k, [one[k]+two[k]+three[k]]) for k in one) 

So, I tried to add lists in values ​​one and two first, and then add value three. Adding lists worked fine, but then when I tried to add a float from the third dictionary, all of a sudden the whole value moved to "None"

 check=dict((k, [one[k]+two[k]]) for k in one) {'a': [[1, 2, 2.4, 3.4]], 'c': [[5, 6, 5.6, 7.6]], 'b': [[3, 4, 3.5, 4.5]]} new=dict((k, v.append(three[k])) for k,v in check.items()) {'a': None, 'c': None, 'b': None} 
+13
source share
4 answers

As a one-line, with a dictionary understanding:

 new = {key: value + two[key] + [three[key]] for key, value in one.iteritems()} 

This creates new lists by combining a list from one with a corresponding list from two , placing one value in three in a temporary list to simplify concatenation.

Or with updating the for one loop in place:

 for key, value in one.iteritems(): value.extend(two[key]) value.append(three[key]) 

This uses list.extend() to update the original list in place using the list of two and list.append() to add a single value from three .

If you did wrong:

  • your first attempt creates a new list with values ​​from one , two and three nested inside, rather than concatenating existing lists. Your attempt to clear this just copied these nested lists.

  • Your second attempt did not work, because the value in three not a list, and therefore cannot be combined. I created a new list only for this value.

  • Your last attempt should not use list.append() in the generator expression, because you store the return value of this method, which is always None (changing it is stored in v directly, and the list does not need to be returned again).

Demonstration of the first approach:

 >>> one={'a': [1, 2], 'c': [5, 6], 'b': [3, 4]} >>> two={'a': [2.4, 3.4], 'c': [5.6, 7.6], 'b': [3.5, 4.5]} >>> three={'a': 1.2, 'c': 3.4, 'b': 2.3} >>> {key: value + two[key] + [three[key]] for key, value in one.iteritems()} {'a': [1, 2, 2.4, 3.4, 1.2], 'c': [5, 6, 5.6, 7.6, 3.4], 'b': [3, 4, 3.5, 4.5, 2.3]} 
+14
source

Free dictionary, number and keys

The problems with your attempt are covered by @MartijnPieters solution.

For a generic solution, consider using itertools.chain for itertools.chain for multiple dictionaries. You can also use defaultdict for a more general case, when you do not find the same keys in each dictionary.

 from collections import defaultdict from itertools import chain from operator import methodcaller # dictionaries with non-equal keys, values all lists for simplicity one = {'a': [1, 2], 'c': [5, 6], 'b': [3, 4], 'e': [6.2]} two = {'a': [2.4, 3.4], 'c': [5.6, 7.6], 'b': [3.5, 4.5], 'f': [1.3]} three = {'a': [1.2], 'c': [3.4], 'b': [2.3], 'e': [3.1]} # initialise defaultdict of lists dd = defaultdict(list) # iterate dictionary items dict_items = map(methodcaller('items'), (one, two, three)) for k, v in chain.from_iterable(dict_items): dd[k].extend(v) print(dd) # defaultdict(list, # {'a': [1, 2, 2.4, 3.4, 1.2], # 'b': [3, 4, 3.5, 4.5, 2.3], # 'c': [5, 6, 5.6, 7.6, 3.4], # 'e': [6.2, 3.1], # 'f': [1.3]}) 

Note that defaultdict is a subclass of dict so there is usually no need to convert the result to a regular dict .

+2
source

See this help or not:

 >>> dic={} >>> k=[] >>> for i in 'abc': k=one[i]+two[i] k.append(three[i]) dic[i]=k >>> dic {'c': [5, 6, 5.6, 7.6, 3.4], 'a': [1, 2, 2.4, 3.4, 1.2], 'b': [3, 4, 3.5, 4.5, 2.3]} 
0
source

A reliable solution. =

 def FullMergeDict(D1, D2): for key, value in D1.items(): if key in D2: if type(value) is dict: FullMergeDict(D1[key], D2[key]) else: if type(value) in (int, float, str): D1[key] = [value] if type(D2[key]) is list: D1[key].extend(D2[key]) else: D1[key].append(D2[key]) for key, value in D2.items(): if key not in D1: D1[key] = value if __name__ == '__main__': X = { 'a': 'aaa', 'c': [1,3,5,7], 'd': 100, 'e': {'k': 1, 'p': 'aa','t': [-1,-2]}, 'f': {'j':1} } Y = { 'b': 'bbb', 'd': 200, 'e': {'k': 2, 'p': 'bb','o': [-4]}, 'c': [2,4,6], 'g': {'v':2} } FullMergeDict(X, Y) exit(0) 

Result:

  X = { 'a': 'aaa', 'b': 'bbb', 'c': [1, 3, 5, 7, 2, 4, 6], 'd': [100, 200], 'e': {'k': [1, 2], 'o': [-4], 'p': ['aa', 'bb'], 't': [-1, -2]}, 'f': {'j': 1}, 'g': {'v': 2}} 
0
source

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


All Articles