Reputation: 35
I read a code in a book 'Think Python'. This code gets stuck at the inverse[val].[key]
with an error:
'str' object has no attribute 'append''
Which makes sense as inverse[val]
contains a string object.
Here d is the input dictionary.
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
The input dictionary is {'a': 1, 'p': 1, 'r': 2, 't': 1, 'o': 1}
The expected output is {1: ['a', 'p', 't', 'o'], 2: ['r']}
How do I implement this, by modifying the given block of code?
Upvotes: 2
Views: 1031
Reputation: 7846
You can also follow a different approach in which you take all values from your dictionary and match each value with the keys that have this value in the initial dictionary:
def invert_dict(d):
values = set(d.values())
inverse = dict((v,[k for k in d.keys() if d[k]==v]) for v in values)
return inverse
inv = invert_dict({'a': 1, 'p': 1, 'r': 2, 't': 1, 'o': 1})
print(inv)
Output:
{1: ['a', 'p', 't', 'o'], 2: ['r']}
Upvotes: 0
Reputation: 7610
A one-liner using reduce:
inverted_dict = reduce((lambda inverted_dict, key: inverted_dict.setdefault(dd[key], []).append(key) or inverted_dict), d, {})
Output:
{1: ['t', 'o', 'p', 'a'], 2: ['r']}
Upvotes: 0
Reputation: 261
try this:
def invert_dict(data):
inverse = {}
for key, value in data.items():
if value not in inverse:
inverse[value] = [key]
else:
inverse[value].append(key)
return inverse
Upvotes: 0
Reputation: 164623
You can use collections.defaultdict
to create a dictionary of lists. Then append to dictionary values while iterating your input dictionary.
from collections import defaultdict
d_in = {'a': 1, 'p': 1, 'r': 2, 't': 1, 'o': 1}
d_out = defaultdict(list)
for k, v in d_in.items():
d_out[v].append(k)
print(d_out)
defaultdict(<class 'list'>, {1: ['a', 'p', 't', 'o'], 2: ['r']})
Your code can be improved by iterating keys and values simultaneously via dict.items
, instead of iterating keys and manually extracting the value. In addition, your indentation is incorrect. After resolving these issues:
def invert_dict(d):
inverse = dict()
for key, val in d.items():
if val not in inverse:
inverse[val] = [key]
else:
inverse[val].append(key)
return inverse
Upvotes: 2