Reputation: 123
I have a defaultdict(list) where my keys are of type tuple and my values are a list of tuples. I want to reverse this dictionary and I have already tried using the zip function and this doesn't work
A sample of my dictionary structure is below
{(2, '-', 3): [('Canada', 'Trudeau'),('Obama', 'USA')]}
Is there anyway to reverse this so I get the keys and values the other way round
Upvotes: 3
Views: 253
Reputation: 103998
Since you have a dict of lists, you need to make the lists an immutable type to use as a key in a Python dict.
You can make the list values tuples:
>>> di={(2, '-', 3): [('Canada', 'Trudeau'),('Obama', 'USA')]}
>>> {tuple(v):k for k, v in di.items()}
{(('Canada', 'Trudeau'), ('Obama', 'USA')): (2, '-', 3)}
Or turn them into strings:
>>> {repr(v):k for k, v in di.items()}
{"[('Canada', 'Trudeau'), ('Obama', 'USA')]": (2, '-', 3)}
With either, you can turn the key back into a list if need be:
>>> from ast import literal_eval
>>> literal_eval("[('Canada', 'Trudeau'), ('Obama', 'USA')]")
[('Canada', 'Trudeau'), ('Obama', 'USA')]
>>> list((('Canada', 'Trudeau'), ('Obama', 'USA')))
[('Canada', 'Trudeau'), ('Obama', 'USA')]
(BTW: Don't use eval
if code that might have any outside strings -- use ast.literal_eval in production code as in the example here.)
Lastly, consider this dict:
di={'key 1':'val', 'key 2': 'val', 'key 3': 'val'}
When you reverse the keys and values you will loose data as each key 'val' is added.
You can use a default dict to solve duplicate values becoming keys:
dd=defaultdict(list)
for k, v in di.items():
dd[v].append(k)
>>> dd
defaultdict(<type 'list'>, {'val': ['key 1', 'key 2', 'key 3']})
Upvotes: 7
Reputation: 53633
Unless I'm misunderstanding what you mean by "reverse" (swapping keys for values, and vice-versa):
NB: As other answers have suggested, if you cast your lists to some immutable type, you can use those as keys in the dict.
Upvotes: 1
Reputation: 304355
If you mean for each tuple from the list to be a key, then this is quite simple (It doesn't matter whether D is a dict
or defaultdict
here)
>>> D = {(2, '-', 3): [('Canada', 'Trudeau'),('Obama', 'USA')]}
>>> {k1: k for k, v in D.items() for k1 in v}
{('Canada', 'Trudeau'): (2, '-', 3), ('Obama', 'USA'): (2, '-', 3)}
Upvotes: 0
Reputation: 7517
You can't do it as it, because your values are mutable: [('Canada', 'Trudeau'),('Obama', 'USA')]
is a list and it can't be a key in a dictionary. Maybe you can change that first?
Upvotes: 2