Reputation: 3
This is my code:
def inverse_dict(my_dict):
new_dict = {}
new_key = ''
for new_value in my_dict:
new_list = [new_value]
new_key = my_dict[new_value]
if new_key in new_dict:
new_list.append(new_dict[new_key])
new_list = sorted(new_list)
new_dict[new_key] = new_list
return new_dict
And my main:
def main():
print(inverse_dict({'cc': 'dd', 'ab': 'cd', 'bb': 'cd'}))
print(inverse_dict({'b': 'd', 'c': 'd', 'a': 'd'}))
I want that my input will be:
{'cd': ['ab', 'bb'], 'dd': ['cc']}
{'d': ['a', 'b', 'c']}
But instead I get error and if I delete the line that i sort my list my input looks like:
{'dd': ['cc'], 'cd': ['bb', ['ab']]}
{'d': ['a', ['c', ['b']]]}
what can I do?
Upvotes: 1
Views: 187
Reputation: 880
Below function gives correct result:
def inverse_dict(dict_):
inverse_dict = dict() # Set an empty dictionary
for key, value in dict_.items():
try:
# If list, add key into list; otherwise it will throw exeption
inverse_dict[value].append(key)
except AttributeError:
# AttributeError means value has item but not list
inverse_dict[value] = [inverse_dict[value], key]
except KeyError:
# KeyError means there isn't any item in the new dictionary
inverse_dict[value] = key
return inverse_dict
Upvotes: 0
Reputation: 781004
You're appending a list to a list, which nests it inside. You should concatenate them:
new_list += new_dict[new_key]
But even simpler would be to not create a new list, just append to the list that's in the key.
for new_key, new_value in enumerate(my_dict):
if new_value in new_dict:
new_dict[new_value].append(new_key)
new_dict[new_value] = sorted(new_dict[new_value])
else
new_dict[new_value] = [new_key]
This is also a good use for a defaultdict
.
Upvotes: 1
Reputation: 164673
You should use collections.defaultdict
for this problem.
The problem with your code is that, to add the elements of a list to another list, you need list.extend
instead of list.append
. This answer provides more detail:
Difference between append vs. extend list methods in Python
from collections import defaultdict
def inverse_dict(d):
res = defaultdict(list)
for k, v in d.items():
res[v].append(k)
return res
print(inverse_dict({'cc': 'dd', 'ab': 'cd', 'bb': 'cd'}))
# defaultdict(<class 'list'>, {'dd': ['cc'], 'cd': ['ab', 'bb']})
print(inverse_dict({'b': 'd', 'c': 'd', 'a': 'd'}))
# defaultdict(<class 'list'>, {'d': ['b', 'c', 'a']})
Explanation for above solution
collections.defaultdict
allows you to specify a default value for arbitrary keys.list
.list.append
to add keys from the original dictionary to values set as keys of your new dictionary.Upvotes: 3
Reputation: 16935
The values of new_dict
are lists. When you append a list to another list, you get nested lists. You want to extend
the list by another list:
>>> def inverse_dict(my_dict):
... new_dict = {}
... new_key = ''
... for new_value in my_dict:
... new_list = [new_value]
... new_key = my_dict[new_value]
... if new_key in new_dict:
... new_list.extend(new_dict[new_key])
... new_list = sorted(new_list)
... new_dict[new_key] = new_list
... return new_dict
...
>>> print(inverse_dict({'cc': 'dd', 'ab': 'cd', 'bb': 'cd'}))
{'dd': ['cc'], 'cd': ['ab', 'bb']}
>>> print(inverse_dict({'b': 'd', 'c': 'd', 'a': 'd'}))
{'d': ['a', 'b', 'c']}
Upvotes: 1