Search code examples
pythonpython-3.xdictionarymerge

Python3 dictionary merge based on values


I have a dictionary composed of {key: value}.

I select a set of keys from this dictionary.

I'd like to build a new dictionary with {keyA: set of all keys which have the same value as keyA}.

I already have a solution: Is there a faster way to do it?

It seems very slow to me, and I imagine I'm not the only one in this case!

for key1 in selectedkeys:
    if key1 not in seen:
        seen.add(key1)
        equal[key1] = set([key1])#egual to itself
        for key2 in selectedkeys:
            if key2 not in seen and dico[key1] == dico[key2]:
                equal[key1].add(key2)
        seen.update(equal[key1])

Solution

  • So you want to create a dictionary that maps key to "the set of all keys which have the same value as key" for each selected key in a given source dictionary.

    Thus, if the source dictionary is:

    {'a': 1, 'b': 2, 'c': 1, 'd': 2, 'e': 3, 'f': 1, 'g': 3)
    

    and the selected keys are a, b, and e, the result should be:

    {'a': {'a', 'c', 'f'}, 'e': {'g', 'e'}, 'b': {'b', 'd'}}
    

    One way to achieve this would be to use a defaultdict to build a value to key table, and then use that to build the required result from the specified keys:

    from collections import defaultdict
    
    def value_map(source, keys):
        table = defaultdict(set)
        for key, value in source.items():
            table[value].add(key)
        return {key: table[source[key]] for key in keys}
    
    source = {'a': 1, 'b': 2, 'c': 1, 'd': 2, 'e': 3, 'f': 1, 'g': 3)
    
    print(value_map(source, ['a', 'b', 'e']))
    

    Output:

    {'a': {'a', 'c', 'f'}, 'e': {'g', 'e'}, 'b': {'b', 'd'}}