Clement Attlee
Clement Attlee

Reputation: 733

how to reconfigure this dictionary to change its keys

Let's say I have this dictionary:

>>> dic = {('a', 'l'):3, ('a', 'p'):2, ('b', 'l'):4, ('b', 'p'):1}

How can I edit it so I can have it like this:

>>> dic_new = {'a':{'l':3, 'p':2}, 'b':{'l':4, 'p':1}}

Whenever I change the keys I get an error. I am confused.

Upvotes: 2

Views: 91

Answers (3)

Austin
Austin

Reputation: 26039

You can use groupby + OrderedDict:

from itertools import groupby
from collections import OrderedDict

dic = {('a', 'l'):3, ('a', 'p'):2, ('b', 'l'):4, ('b', 'p'):1}

dic = OrderedDict(dic)
new_d = {}

for k, g in groupby(dic, lambda x: x[0]):
    for x in g:
        if k in new_d:
            new_d[k].update({x[1]: dic[x]})
        else:
            new_d[k] = {x[1]: dic[x]}

print(new_d)
# {'a': {'l': 3, 'p': 2}, 'b': {'l': 4, 'p': 1}}

Or in case where you can guarantee dictionaries are ordered as per first value in tuple key, you can straightaway ignore OrderedDict.

Upvotes: 0

Elro444
Elro444

Reputation: 136

You can iterate through the original dictionary and create a new one as you find keys:

dic = {('a', 'l'):3, ('a', 'p'):2, ('b', 'l'):4, ('b', 'p'):1}
dic_new = {}
for (new_key, new_sub_key),value in dic.items():
    if new_key not in dic_new:
        dic_new[new_key] = {}
    dic_new[new_key][new_sub_key] = value
print(dic_new)

Output

{'a': {'l': 3, 'p': 2}, 'b': {'l': 4, 'p': 1}}

Upvotes: 1

chepner
chepner

Reputation: 531798

In each case, you want to set d2[k1][k2]=v whereever you have d1[k1,k2]=v. The simplest way to do this is to start with a defaultdict.

>>> from collections import defaultdict
>>> d1 = {('a', 'l'):3, ('a', 'p'):2, ('b', 'l'):4, ('b', 'p'):1}
>>> d2 = defaultdict(dict)
>>> for k1, k2 in d1:
...    d2[k1][k2] = d[k1,k2]
...
>>> d2
defaultdict(<class 'dict'>, {'a': {'l': 3, 'p': 2}, 'b': {'l': 4, 'p': 1}})
>>> dict(d2)
{'a': {'l': 3, 'p': 2}, 'b': {'l': 4, 'p': 1}}

If you don't want to use a defaultdict, use the setdefault method.

d2 = {}
for k1, k2 in d1:
    d2.setdefault(k1, {})[k2] = d1[k1,k2]

Upvotes: 1

Related Questions