List Of Tuples To Nested Dictionary Without Overriding
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"