## martedì 24 maggio 2011

### A method to exchange keys and values in a python dictionary

Around the web i've found this method to exchange keys and values in a python dictionary:

the_dict = { 'a': 1, 'b': 2, 'c': 3 }
inverted_dict = dict(zip(*zip(*the_dict.items())[::-1]))


output:
{ 1:'a', 2:'b', 3:'c' }


it is nice isn't it?
but how does it work?
The main idea is to split keys and values in a list of two n-tuples $$[ (k_1,...,k_n) , (v_1,...,v_n)] ,$$
switch the tuples and re-create a dictionary.

ingredients are:
1 - operator * (also known as 'splat' operator) that is able to unpack a list
2 - zip function that returns a list of tuples, where the i-th tuple contains the i-th element from each of the argument sequences or iterable
3 - a_list[::-1] to revert a_list

We can unpack the algorithm in those 5 nested steps:
a - the_dict.items()
b - zip(*the_dict.items())
c - zip(*the_dict.items())[::-1]
d - zip(*zip(*the_dict.items())[::-1])
e - dict(zip(*zip(*the_dict.items())[::-1]))


a - with the_dict.items() we obtain:
 [('a', 1), ('b', 2), ('c', 3)]

b - then, using * operator in the zip function:
zip(*the_dict.items())
we are doing:
zip(('a', 1), ('b', 2), ('c', 3) )
obtaining:
[('a', 'b', 'c'), (1, 2, 3)]


c - with [::-1] we actually switch key and values
zip(*the_dict.items())[::-1] = [('a', 'b', 'c'), (1, 2, 3)][::-1]
=
[('a', 'b', 'c'), (1, 2, 3)]


d - with the second zip * pair we re-unpack the list to recreate the 3 pairs:
zip(*zip(*the_dict.items())[::-1]) =
zip(*[('a', 'b', 'c'), (1, 2, 3)]) =zip(('a', 'b', 'c'), (1, 2, 3) )
=
[('a', 1), ('b', 2), ('c', 3)]


e - now our new dict is almost cooked, we use dict() function to complete the opera:
dict(zip(*zip(*the_dict.items())[::-1]))
=
dict ([('a', 1), ('b', 2), ('c', 3)])
the output:{ 1:'a', 2:'b', 3:'c' }all this stuff in 1 row.



#### 1 commento:

Anonimo ha detto...

Nice Post. This post helped me in my school assignment. Thanks Alot