Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

better one-liner to flip keys and values of a dictionary

Tags:

python

I've written a one-liner to accomplish this:

vocab_tag = dict(zip(*reversed(zip(*tag_vocab.items()))))

Can anybody write one that's more comprehensible/direct?

like image 263
Maus Avatar asked Jan 02 '13 23:01

Maus


3 Answers

A readable and short dict comprehension is probably the best one can do:

vocab_tage = {value: key for key, value in tag_vocab.items()}

Pre 2.7, dictionary comprehensions don't exist, but we can replace them trivially with dict() and a generator expression:

vocab_tage = dict((value, key) for key, value in tag_vocab.items())

It's worth noting that this presumes there are no keys with the same value (as does the example in the question).

like image 150
Gareth Latty Avatar answered Sep 30 '22 14:09

Gareth Latty


Try this one-liner: dict(map(reversed, table.items()))

like image 27
Noctis Skytower Avatar answered Sep 30 '22 14:09

Noctis Skytower


Performance + Readability

Considering time performance, dictionary comprehension is the best solution. It is both readable and performant.

Given a dictionary, a, defined as

a = {'1' : 'a', '2' : 'b', '3' : 'c', '4' : 'd'}

the implementations perform in the following manner:

Original

%%timeit
b = dict(zip(*reversed(zip(*a.items()))))

100000 loops, best of 3: 3.09 µs per loop

Gareth Latty's answer

%%timeit 
c = {v: k for k, v in a.items()}

1000000 loops, best of 3: 776 ns per loop

Noctis Skytower's answer

%%timeit 
d = dict(map(reversed, a.items()))

100000 loops, best of 3: 4.38 µs per loop

Modification to Gareth Latty's answer using .iteritems() method

If using < Python 3, .iteritems() will perform slightly faster and is more memory efficient.

%%timeit
e = {v: k for k, v in a.iteritems()}

1000000 loops, best of 3: 598 ns per loop
like image 37
tmthydvnprt Avatar answered Sep 30 '22 14:09

tmthydvnprt