Sorry for the wordy and confusing title, I found it’s hard to describe what I wanted while trying to search for an existing answer on the Internet. I wanted a simpler code for merging two dict-type without looping. I didn’t find I wanted, so I wrote one on my own. To show you clearly, considering with only two dicts in Python 3:
from pprint import pprint d1 = {'A': 1, 'B': 2} d2 = {'A': 3, 'C': 4} d = dict((key, (d1.get(key, 0), d2.get(key, 0))) \ for key in d1.keys() | d2.keys()) pprint(d)
{'A': (1, 3), 'B': (2, 0), 'C': (0, 4)}
So, this should clarify. In Python 2.X, you need to explicitly use set-type for union operation on two dict-types keys:
from pprint import pprint d1 = {'A': 1, 'B': 2} d2 = {'A': 3, 'C': 4} d = dict((key, (d1.get(key, 0), d2.get(key, 0))) \ for key in set(d1.keys()) | set(d2.keys())) pprint(d)
{'A': (1, 3), 'B': (2, 0), 'C': (0, 4)}
A key may not appear in the other dict-type, which is the case I have. Although I only need to merge two dict-types, but why not generalize it for arbitrary number of dict-types:
from pprint import pprint import itertools import random import string DICTS = 5 KEYPOOL= string.ascii_uppercase[:DICTS] KEYS = 3 def random_dict(i): d = dict((key, random.randint(1, 10)) \ for key in random.sample(KEYPOOL, KEYS)) print('=== dict %d ===' % i) pprint(d) return d dicts = [random_dict(i) for i in range(DICTS)] d = dict((key, tuple(d.get(key, 0) for d in dicts)) for key in \ set(itertools.chain.from_iterable(d.keys() for d in dicts))) print('=== result ===') pprint(d)
=== dict 0 === {'A': 4, 'B': 10, 'C': 8} === dict 1 === {'B': 5, 'C': 3, 'D': 3} === dict 2 === {'A': 8, 'D': 3, 'E': 10} === dict 3 === {'A': 7, 'C': 2, 'D': 10} === dict 4 === {'A': 8, 'C': 3, 'D': 6} === result === {'A': (4, 0, 8, 7, 8), 'B': (10, 5, 0, 0, 0), 'C': (8, 3, 0, 2, 3), 'D': (0, 3, 3, 10, 6), 'E': (0, 0, 10, 0, 0)}
It uses itertools.chain.from_iterable to chain all iterables from dict.keys(), then convert to set-type to remove duplicates. Generating a tuple-type with a generator which loops through all dict-types for values by key, then forming another tuple-type with the key, so it can be converted into an item of the final dict-type.
Note that the code use tuple-type to contains the values, not list-type as title says, that’s up to you, simply replace tuple-type with with list-type.
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.