I have been working on this forever. I have the following dictionary.
Subject1='Math'
Subject2='English'
Subject3='Chemstry'
Subject4='Physics'
Subject5='Geology'
Subject6='PE'
Subject7='Music'
Subject8='Psychology'
Subject9='Politics'
Subject10='Acting'
dict_1 = {(Subject1, Subject2):['Michael','James','Lydia'],
(Subject3, Subject4):['Michael','Lydia','James'],
(Subject5, Subject6):['Tom'],
(Subject7, Subject8):[],
(Subject9, Subject10):[]
}
I want to inverse the dictionary so that it will look like:
{['Michael', 'James', 'Lydia']: {(Subject1, Subject2), (Subject3, Subject4)},
['Tom']: {(Subject5, Subject6)},
[]: {(Subject7, Subject8), (Subject9, Subject10)} }
I tried
from collections import defaultdict
new_tel = defaultdict(list)
for key, value in dict_1.items():
new_tel[value].append(key)
This worked for hashable type but not unhashable type list. Maybe I can join the string of ['Michael','James','Lydia']
to 'James Lydia Michael
' so that it can be a valid key? How do I sort the elements in the list ['Michael','James','Lydia']
and ['Michael','Lydia','James']
so that they are in alphabetical order before I join them?
This is a more achievable output:
{'James Lydia Michael': {(Subject1, Subject2), (Subject3, Subject4)},
'Tom': {(Subject5, Subject6)},
'None': {(Subject7, Subject8), (Subject9, Subject10)} }
CodePudding user response:
Dictionary keys can't be lists but it can be tuples. So you can do something like below. Sort the values, make them tuples to use as keys and use dict.setdefault
:
out = {}
for k,v in dict_1.items():
out.setdefault(tuple(sorted(v)), set()).add(k)
Output:
{('James', 'Lydia', 'Michael'): {('Chemstry', 'Physics'), ('Math', 'English')},
('Tom',): {('Geology', 'PE')},
(): {('Music', 'Psychology'), ('Politics', 'Acting')}}
CodePudding user response:
As told in the question comments lists are unhashable. if you can use tuple instead, "Dict Comprehensions" is a good way. More info: https://www.python.org/dev/peps/pep-0274/.
dict_reverse = {tuple(dict_1[key]): key for key in dict_1.keys()}
CodePudding user response:
Easiest would be to use a tuple
as key type
for key, value in dict_1.items():
new_tel[tuple(sorted(value))].append(key)
{('James', 'Lydia', 'Michael'): [('Math', 'English'), ('Chemstry', 'Physics')],
('Tom',): [('Geology', 'PE')],
(): [('Music', 'Psychology'), ('Politics', 'Acting')]})
If you join to set the key type as str
for key, value in dict_1.items():
new_tel[" ".join(sorted(value))].append(key)
{'James Lydia Michael': [('Math', 'English'), ('Chemstry', 'Physics')],
'Tom': [('Geology', 'PE')],
'': [('Music', 'Psychology'), ('Politics', 'Acting')]})