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']}
Related posts
- An example using Python's groupby and defaultdict to do the same task — posted 2014-10-09
- python enum types — posted 2012-10-10
- Python data object motivated by a desire for a mutable namedtuple with default values — posted 2012-08-03
- How to sort a list of dicts in Python — posted 2010-04-02
- Python setdefault example — posted 2010-02-09
- How to conditionally replace items in a list — posted 2008-08-22
Comments
Thanks - your last example (invert_dol_nonunique) was exactly what I was looking for!
Thanks - very good article. Example 2 saved my from using OrderedDict function.
I had dictionaries like this {'a': 1, 'b':2, 'c':0, 'EMPTY':0}. In one function I want to retreive number based on literal and in second function I want to get literal but this was diffeculty since elements are not unique. I've used Example 2 and declared {1: ['a'], 2 : ['b'], 0" :['c', EMPTY]} to be used by second function (this way I can choose if 'c' or 'EMPTY' I will use) and I used inverted dictionary in function one.
disqus:3596338052