Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Switch key and value in a dictionary of sets

I have dictionary something like:

d1 = {'0': {'a'}, '1': {'b'}, '2': {'c', 'd'}, '3': {'E','F','G'}}

and I want result like this

d2 = {'a': '0', 'b': '1', 'c': '2', 'd': '2', 'E': '3', 'F': '3', 'G': '3'}

so I tried

d2 = dict ((v, k) for k, v in d1.items())

but value is surrounded by set{}, so it didn't work well... is there any way that I can fix it?

like image 568
goldenasian Avatar asked Dec 23 '22 18:12

goldenasian


2 Answers

You could use a dictionary comprehension:

{v:k for k,vals in d1.items() for v in vals}
# {'a': '0', 'b': '1', 'c': '2', 'd': '2', 'E': '3', 'F': '3', 'G': '3'}

Note that you need an extra level of iteration over the values in each key here to get a flat dictionary.

like image 146
yatu Avatar answered Dec 25 '22 07:12

yatu


Another dict comprehension:

>>> {v: k for k in d1 for v in d1[k]}
{'a': '0', 'b': '1', 'c': '2', 'd': '2', 'E': '3', 'F': '3', 'G': '3'}

Benchmark comparison with yatu's:

from timeit import repeat
setup = "d1 = {'0': {'a'}, '1': {'b'}, '2': {'c', 'd'}, '3': {'E','F','G'}}"
yatu = "{v:k for k,vals in d1.items() for v in vals}"
heap = "{v:k for k in d1 for v in d1[k]}"
for _ in range(3):
    print('yatu', min(repeat(yatu, setup)))
    print('heap', min(repeat(heap, setup)))
    print()

Results:

yatu 1.4274586000000227
heap 1.4059823000000051

yatu 1.4562267999999676
heap 1.3701727999999775

yatu 1.4313863999999512
heap 1.3878657000000203

Another benchmark, with a million keys/values:

setup = "d1 = {k: {k+1, k+2} for k in range(0, 10**6, 3)}"
for _ in range(3):
    print('yatu', min(repeat(yatu, setup, number=10)))
    print('heap', min(repeat(heap, setup, number=10)))
    print()

yatu 1.071519999999964
heap 1.1391495000000305

yatu 1.0880677000000105
heap 1.1534022000000732

yatu 1.0944767999999385
heap 1.1526202000000012

like image 23
Kelly Bundy Avatar answered Dec 25 '22 06:12

Kelly Bundy