Inverting a dictionary with list values

Vestergaardish picture Vestergaardish · Feb 18, 2016 · Viewed 12.9k times · Source

So, I have this index as a dict.

index = {'Testfil2.txt': ['nisse', 'hue', 'abe', 'pind'], 'Testfil1.txt': ['hue', 'abe', 
'tosse', 'svend']}

I need to invert the index so it will be a dict with duplicates of values merged into one key with the 2 original keys as values, like this:

inverse = {'nisse' : ['Testfil2.txt'], 'hue' : ['Testfil2.txt', 'Testfil1.txt'], 
'abe' : ['Testfil2.txt', 'Testfil1.txt'], 'pind' : ['Testfil2.txt'], 'tosse' : 
['Testfil1.txt'], 'svend' : ['Testfil1.txt']

Yes, I typed the above by hand.

My textbook has this function for inverting dictionaries:

def invert_dict(d): 
    inverse = dict() 
    for key in d: 
        val = d[key] 
        if val not in inverse: 
            inverse[val] = [key] 
        else: 
            inverse[val].append(key) 
return inverse

It works fine for simple key:value pairs

BUT, when I try that function with a dict that has lists as values such as my index I get this error message:

invert_dict(index)

Traceback (most recent call last):
    File "<pyshell#153>", line 1, in <module>
invert_dict(index)
    File "<pyshell#150>", line 5, in invert_dict
if val not in inverse:
TypeError: unhashable type: 'list'

I have searched for an hour looking for a solution, the book is no help, and I suspect that I can use tuples in some way, but I am not sure how. Any help?

Answer

ᴀʀᴍᴀɴ picture ᴀʀᴍᴀɴ · Feb 18, 2016

My solution for reversing a dictionary. However, it creates a new dictionary new_dic:

new_dic = {}
for k,v in index.items():
    for x in v:
        new_dic.setdefault(x,[]).append(k)

Output :

{'tosse': ['Testfil1.txt'], 'nisse': ['Testfil2.txt'], 'svend': ['Testfil1.txt'], 'abe': ['Testfil1.txt', 'Testfil2.txt'], 'pind': ['Testfil2.txt'], 'hue': ['Testfil1.txt', 'Testfil2.txt']}