How do I exchange keys with values in a dictionary?

PythonDictionaryMappingReverse

Python 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

  1. More than one key shares the same value. For example {'one':1,'two':1}. The new dictionary can only have one item with key 1.
  2. 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.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionRoee AdlerView Question on Stackoverflow
Solution 1 - PythonlioriView Answer on Stackoverflow
Solution 2 - PythonJavierView Answer on Stackoverflow
Solution 3 - PythonSilentGhostView Answer on Stackoverflow
Solution 4 - PythonsunqiangView Answer on Stackoverflow
Solution 5 - PythonAkavallView Answer on Stackoverflow
Solution 6 - PythonHanan ShteingartView Answer on Stackoverflow
Solution 7 - PythonAlasdairView Answer on Stackoverflow
Solution 8 - PythonpkitView Answer on Stackoverflow
Solution 9 - PythonbalphaView Answer on Stackoverflow
Solution 10 - PythonSunny PatelView Answer on Stackoverflow
Solution 11 - Pythonshadow2097View Answer on Stackoverflow
Solution 12 - Pythonuser10084443View Answer on Stackoverflow
Solution 13 - PythonIlya ProkinView Answer on Stackoverflow
Solution 14 - PythonpegahView Answer on Stackoverflow
Solution 15 - PythonDevesh SainiView Answer on Stackoverflow
Solution 16 - PythonGravity GraveView Answer on Stackoverflow
Solution 17 - PythontimgebView Answer on Stackoverflow
Solution 18 - PythonAlketCecajView Answer on Stackoverflow
Solution 19 - PythonLuWilView Answer on Stackoverflow