Swapping key-value pairs in a dictionary

Kshitij Saraogi picture Kshitij Saraogi · Jul 13, 2015 · Viewed 7.9k times · Source

I am looking for ways to swap all the key-value pairs of a given dictionary.

So far I could think of one way for doing it:

Ex:

>>>a = { 0: 'a', 1 : 'b', 2 : 'c' }
>>> {value : key for key,value in a.items()}
{'a': 0, 'b': 1, 'c' : 2}

But for this I would have to use extra space for declaring another dictionary.
I would like to know the methods could I use to swap the key-value pair more space-efficiency.

Answer

poke picture poke · Jul 13, 2015

But for this I would have to use extra space for declaring another dictionary.

Since a dictionary is essentially a lookup table, there is a concrete way it is layed out in memory; the keys are distributed efficiently and just point to values which—by themselves—have no special meaning. Thus, when you want to reverse the mapping, you can’t really use the existing structure; instead you will have to create new dictionary entries from scratch. The dictionary comprehension you have used in your question is a good and clear way to do that.

What you could do however is to reuse the dictionary you already have and add the new keys there (while removing the old ones):

for k in a:
    a[a[k]] = k
    del a[k]

This modifies the same dictionary, so it won’t have the (likely little) overhead of a new dictionary. Note that this assumes that all values are unique too so the mapping can be exactly reversed, and that the set of keys and values don’t share common values. Otherwise, you will run into dictionary size changed exceptions or missing values. You can avoid the former by creating a copy of the dictionary keys (although this means that you have a list to store now too):

for k in list(a):
    if a[k] != k:
        a[a[k]] = k
        del a[k]

A final note: It’s possible that modifying the dictionary multiple times like that might have some remapping side-effects though (to increase the hash table size etc.), but that’s possible implementation detail of CPython (and I’m not too sure about it).