Skip to content Skip to sidebar Skip to footer

List Of Tuples To Nested Dictionary Without Overriding

I need to convert the above list of tuples to nested dictionary without overwriting the value as below in python [('a', '1'), ('b', 'true'), ('b', 'none'), ('a', '2'), ('b'

Solution 1:

Here's one way to do it with collections.defaultdict:

from collections import defaultdict
import pprint

data = [('a', '1'), ('b', 'true'), ('b', 'none'), ('a', '2'), ('b', 'true'), ('a', '3'), ('b', 'false')]

d = defaultdict(lambda: defaultdict(lambda: defaultdict(tuple)))    
for i, j indata:
    if i == 'a':
        p = d[i][j]
    else:
        p[i] += j,

pprint.pprint(d)
# {'a': {'1': defaultdict(<class 'tuple'>, {'b': ('true', 'none')}),
#        '2': defaultdict(<class 'tuple'>, {'b': ('true',)}),
#        '3': defaultdict(<class 'tuple'>, {'b': ('false',)})}}

You could also use the dictionary's setdefault method to return default values for new keys, although the defaultdict approach is much cleaner and faster:

c = {}
for i, j indata:
    if i == 'a':
        q = c.setdefault(i, {}).setdefault(j, {})
    else:
        q[i] = q.setdefault(i, ()) + (j,)

pprint.pprint(c)
# {'a': {'1': {'b': ('true', 'none')},
#        '2': {'b': ('true',)},
#        '3': {'b': ('false',)}}}

Solution 2:

Expanding @MosesKoledoye answer, if the first value in the dictionary is only 'a' and 'b', you know that the outer dictionary will always contain at most one element using 'a' as the key and the inner dictionary will always contain at most one element using 'b' as the key. So in the end you get the same information if it is {'1': ('true', 'none')…. You can convert that to your format simply by wrapping the data in some dictionaries. This means you can do the following

output = defaultdict(tuple)
for i, j in data:
    if i == 'a':
        current = j
    else:
        # i == 'b'
        output[current] += (j, )

This will result in the following:

defaultdict(<type'tuple'>, {'1': ('true', 'none'), '3': ('false',), '2': ('true',)})

Now to get it into a dictionary like yours you can do the following:

output = {k: {'b': v} for k, v inoutput.items()}
ifoutput:
    output = {'a': output}

Resulting in the following:

{'a': {'1': {'b': ('true', 'none')}, '3': {'b': ('false',)}, '2': {'b': ('true',)}}}

Post a Comment for "List Of Tuples To Nested Dictionary Without Overriding"