pythondictionaryindexinginverted-index

Inverting a dictionary with list values


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']}

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:

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'

The book is no help, and I suspect that I can use tuples in some way, but I am not sure how.


Solution

  • I've tried around and you want to use val not in inverse but it can't be checked if a "list is in a dict". (val is a list)

    For your code a simple change will do what you want:

    def invert_dict(d): 
        inverse = dict() 
        for key in d: 
            # Go through the list that is saved in the dict:
            for item in d[key]:
                # Check if in the inverted dict the key exists
                if item not in inverse: 
                    # If not create a new list
                    inverse[item] = [key] 
                else: 
                    inverse[item].append(key) 
        return inverse