How do I exchange keys with values in a dictionary?
PythonDictionaryMappingReversePython Problem Overview
I receive a dictionary as input, and would like to to return a dictionary whose keys will be the input's values and whose value will be the corresponding input keys. Values are unique.
For example, say my input is:
a = dict()
a['one']=1
a['two']=2
I would like my output to be:
{1: 'one', 2: 'two'}
To clarify I would like my result to be the equivalent of the following:
res = dict()
res[1] = 'one'
res[2] = 'two'
Any neat Pythonic way to achieve this?
Python Solutions
Solution 1 - Python
Python 2:
res = dict((v,k) for k,v in a.iteritems())
Python 3 (thanks to @erik):
res = dict((v,k) for k,v in a.items())
Solution 2 - Python
new_dict = dict(zip(my_dict.values(), my_dict.keys()))
Solution 3 - Python
From Python 2.7 on, including 3.0+, there's an arguably shorter, more readable version:
>>> my_dict = {'x':1, 'y':2, 'z':3}
>>> {v: k for k, v in my_dict.items()}
{1: 'x', 2: 'y', 3: 'z'}
Solution 4 - Python
In [1]: my_dict = {'x':1, 'y':2, 'z':3}
Python 3
In [2]: dict((value, key) for key, value in my_dict.items())
Out[2]: {1: 'x', 2: 'y', 3: 'z'}
Python 2
In [2]: dict((value, key) for key, value in my_dict.iteritems())
Out[2]: {1: 'x', 2: 'y', 3: 'z'}
Solution 5 - Python
You can make use of dict comprehensions:
Python 3
res = {v: k for k, v in a.items()}
Python 2
res = {v: k for k, v in a.iteritems()}
Edited: For Python 3, use a.items()
instead of a.iteritems()
. Discussions about the differences between them can be found in iteritems in Python on SO.
Solution 6 - Python
The current leading answer assumes values are unique which is not always the case. What if values are not unique? You will loose information! For example:
d = {'a':3, 'b': 2, 'c': 2}
{v:k for k,v in d.iteritems()}
returns {2: 'b', 3: 'a'}
.
The information about 'c'
was completely ignored.
Ideally it should had be something like {2: ['b','c'], 3: ['a']}
. This is what the bottom implementation does.
Python 2.x
def reverse_non_unique_mapping(d):
dinv = {}
for k, v in d.iteritems():
if v in dinv:
dinv[v].append(k)
else:
dinv[v] = [k]
return dinv
Python 3.x
def reverse_non_unique_mapping(d):
dinv = {}
for k, v in d.items():
if v in dinv:
dinv[v].append(k)
else:
dinv[v] = [k]
return dinv
Solution 7 - Python
You could try:
Python 3
d={'one':1,'two':2}
d2=dict((value,key) for key,value in d.items())
d2
{'two': 2, 'one': 1}
Python 2
d={'one':1,'two':2}
d2=dict((value,key) for key,value in d.iteritems())
d2
{'two': 2, 'one': 1}
Beware that you cannot 'reverse' a dictionary if
- More than one key shares the same value. For example
{'one':1,'two':1}
. The new dictionary can only have one item with key1
. - One or more of the values is unhashable. For example
{'one':[1]}
.[1]
is a valid value but not a valid key.
See this thread on the python mailing list for a discussion on the subject.
Solution 8 - Python
res = dict(zip(a.values(), a.keys()))
Solution 9 - Python
new_dict = dict( (my_dict[k], k) for k in my_dict)
or even better, but only works in Python 3:
new_dict = { my_dict[k]: k for k in my_dict}
Solution 10 - Python
Another way to expand on Ilya Prokin's response is to actually use the reversed
function.
dict(map(reversed, my_dict.items()))
In essence, your dictionary is iterated through (using .items()
) where each item is a key/value pair, and those items are swapped with the reversed
function. When this is passed to the dict
constructor, it turns them into value/key pairs which is what you want.
Solution 11 - Python
Suggestion for an improvement for Javier answer :
dict(zip(d.values(),d))
Instead of d.keys()
you can write just d
, because if you go through dictionary with an iterator, it will return the keys of the relevant dictionary.
Ex. for this behavior :
d = {'a':1,'b':2}
for k in d:
k
'a'
'b'
Solution 12 - Python
Can be done easily with dictionary comprehension:
{d[i]:i for i in d}
Solution 13 - Python
dict(map(lambda x: x[::-1], YourDict.items()))
.items()
returns a list of tuples of (key, value)
. map()
goes through elements of the list and applies lambda x:[::-1]
to each its element (tuple) to reverse it, so each tuple becomes (value, key)
in the new list spitted out of map. Finally, dict()
makes a dict from the new list.
Solution 14 - Python
Hanan's answer is the correct one as it covers more general case (the other answers are kind of misleading for someone unaware of the duplicate situation). An improvement to Hanan's answer is using setdefault:
mydict = {1:a, 2:a, 3:b}
result = {}
for i in mydict:
result.setdefault(mydict[i],[]).append(i)
print(result)
>>> result = {a:[1,2], b:[3]}
Solution 15 - Python
Using loop:-
newdict = {} #Will contain reversed key:value pairs.
for key, value in zip(my_dict.keys(), my_dict.values()):
# Operations on key/value can also be performed.
newdict[value] = key
Solution 16 - Python
If you're using Python3, it's slightly different:
res = dict((v,k) for k,v in a.items())
Solution 17 - Python
Adding an in-place solution:
>>> d = {1: 'one', 2: 'two', 3: 'three', 4: 'four'}
>>> for k in list(d.keys()):
... d[d.pop(k)] = k
...
>>> d
{'two': 2, 'one': 1, 'four': 4, 'three': 3}
In Python3, it is critical that you use list(d.keys())
because dict.keys
returns a view of the keys. If you are using Python2, d.keys()
is enough.
Solution 18 - Python
I find this version the most comprehensive one:
a = {1: 'one', 2: 'two'}
swapped_a = {value : key for key, value in a.items()}
print(swapped_a)
output : {'one': 1, 'two': 2}
Solution 19 - Python
An alternative that is not quite as readable (in my opinion) as some of the other answers:
new_dict = dict(zip(*list(zip(*old_dict.items()))[::-1]))
where list(zip(*old_dict.items()))[::-1]
gives a list of 2 tuples, old_dict
's values and keys, respectively.