Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I exchange keys with values in a dictionary?

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?

like image 909
Roee Adler Avatar asked Jun 23 '09 10:06

Roee Adler


People also ask

Can we access keys using values in dictionary?

If you want to find the key by the value, you can use a dictionary comprehension to create a lookup dictionary and then use that to find the key from the value.

Can we update the value of a key in dictionary?

In order to update the value of an associated key, Python Dict has in-built method — dict. update() method to update a Python Dictionary. The dict. update() method is used to update a value associated with a key in the input dictionary.


18 Answers

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())
like image 186
liori Avatar answered Oct 05 '22 13:10

liori


new_dict = dict(zip(my_dict.values(), my_dict.keys()))
like image 26
Javier Avatar answered Oct 05 '22 13:10

Javier


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'}
like image 25
SilentGhost Avatar answered Oct 05 '22 13:10

SilentGhost


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.

like image 42
Akavall Avatar answered Oct 05 '22 15:10

Akavall


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'}
like image 37
sunqiang Avatar answered Oct 05 '22 14:10

sunqiang


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
like image 30
Hanan Shteingart Avatar answered Oct 05 '22 14:10

Hanan Shteingart


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.

like image 44
Alasdair Avatar answered Oct 05 '22 13:10

Alasdair


res = dict(zip(a.values(), a.keys()))

like image 30
pkit Avatar answered Oct 05 '22 14:10

pkit


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}
like image 28
balpha Avatar answered Oct 05 '22 15:10

balpha


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.

like image 32
Sunny Patel Avatar answered Oct 05 '22 15:10

Sunny Patel


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'
like image 35
shadow2097 Avatar answered Oct 05 '22 13:10

shadow2097


Can be done easily with dictionary comprehension:

{d[i]:i for i in d}
like image 39
user10084443 Avatar answered Oct 05 '22 15:10

user10084443


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.

like image 25
Ilya Prokin Avatar answered Oct 05 '22 15:10

Ilya Prokin


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]}
like image 39
pegah Avatar answered Oct 05 '22 13:10

pegah


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
like image 32
Devesh Saini Avatar answered Oct 05 '22 15:10

Devesh Saini


If you're using Python3, it's slightly different:

res = dict((v,k) for k,v in a.items())
like image 28
Gravity Grave Avatar answered Oct 05 '22 14:10

Gravity Grave


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.

like image 23
timgeb Avatar answered Oct 05 '22 13:10

timgeb


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}

like image 20
AlketCecaj Avatar answered Oct 05 '22 13:10

AlketCecaj