Saltycrane logo

SaltyCrane Blog

Notes on Python, Django, and web development on Ubuntu Linux

    

How to invert a dict in Python

Example 1: If the values in the dictionary are unique and hashable, then I can use Recipe 4.14 in the Python Cookbook, 2nd Edition.

def invert_dict(d):
    return dict([(v, k) for k, v in d.iteritems()])

d = {'child1': 'parent1',
     'child2': 'parent2',
     }
print invert_dict(d)
{'parent2': 'child2', 'parent1': 'child1'}

Example 2: If the values in the dictionary are hashable, but not unique, I can create a dict of lists as an inverse.

def invert_dict_nonunique(d):
    newdict = {}
    for k, v in d.iteritems():
        newdict.setdefault(v, []).append(k)
    return newdict

d = {'child1': 'parent1',
     'child2': 'parent1',
     'child3': 'parent2',
     'child4': 'parent2',
     }
print invert_dict_nonunique(d)
{'parent2': ['child3', 'child4'], 'parent1': ['child1', 'child2']}

Example 3: If I am starting with a dict of lists, where lists contain unique hashable items, I can create an inverse as shown below.

def invert_dol(d):
    return dict((v, k) for k in d for v in d[k])

d = {'child1': ['parent1'],
     'child2': ['parent2', 'parent3'],
     }
print invert_dol(d)
{'parent3': 'child2', 'parent2': 'child2', 'parent1': 'child1'}

Example 4: If I am starting with a dict of lists, where lists contain non-unique hashable items, I can create another dict of lists as an inverse.

def invert_dol_nonunique(d):
    newdict = {}
    for k in d:
        for v in d[k]:
            newdict.setdefault(v, []).append(k)
    return newdict

d = {'child1': ['parent1'],
     'child2': ['parent1'],
     'child3': ['parent2'],
     'child4': ['parent2'],
     'child5': ['parent1', 'parent2'],
     }
print invert_dol_nonunique(d)
{'parent2': ['child3', 'child4', 'child5'], 'parent1': ['child1', 'child2', 'child5']}

1 Comment — feed icon Comments feed for this post


#1 MartinG commented on 2008-05-01:

Thanks - your last example (invert_dol_nonunique) was exactly what I was looking for!

Post a comment

Required
Required, but not displayed
Optional

Format using Markdown. (No HTML.)
  • Code blocks: prefix each line by at least 4 spaces or 1 tab (and a blank line before and after)
  • Code span: surround with backticks
  • Blockquotes: prefix lines to be quoted with >
  • Links: <URL>
  • Links w/ description: [description](URL)
Created with Django | Hosted by Slicehost