Convenient way to handle deeply nested dictionary in Python

2024/10/5 7:19:47

I have a deeply nested dictionary in python thats taking up a lot of room. Is there a way to abbreviate something like this

master_dictionary['sub_categories'][sub_cat_name]['attributes'][attribute_name]['special_type']['nested_children'][child_cat_name][color] = blue

to this for example

nested_child_info[color] = blue

And still have it edit the dictionary ? I hope that makes sense.

Answer

Similar to @fferri. You will always have to specify the items in a long list. Get a reference to the final dict using reduce and getitem:

from functools import reduce
from operator import getitemd = {1:{2:{3:{4:5}}}}foo = 2
items = [1,foo,3]
result = d
info = reduce(getitem, items, d)>>> info[4]
5
>>> d
{1: {2: {3: {4: 5}}}}
>>> info[4] = 99
>>> d
{1: {2: {3: {4: 99}}}}

I was also playing around with a class but it doesn't seem to have many advantages - except you could customize a key error exception so that the error message would tell you which key at which depth is missing.

class Drilldown:def __init__(self, d, path):#self.final = reduce(getitem, path, d)self.final = dfor i, item in enumerate(path, 1):try:self.final = self.final[item]except KeyError as e:msg = ''.join('[{}]' for _ in range(i))msg = msg.format(*path[:i])msg = 'The last key in the path "{}" does not exist'.format(msg)e.args = [msg]raisedef __call__(self, item):return self.final[item]def __setitem__(self, item, value):self.final[item] = valuedef __getitem__(self, item):return self.final[item]def __str__(self):return str(self.final)def __repr__(self):return repr(self.final)>>> z = 19
>>> items = [1,2,z]
>>> q = Drilldown(d,items)
Traceback (most recent call last):File "<pyshell#68>", line 1, in <module>q = Drilldown(d,items)File "C:\pyProjects33\tmp.py", line 32, in __init__self.final = self.final[item]
KeyError: 'The last key in the path "[1][2][19]" does not exist'>>> 
>>> #normal usage
>>> items = [1,2,3]
>>> q = Drilldown(d,items)
>>> d
{1: {2: {3: {4: 5}}}}
>>> q
{4: 5}
>>> q(4)
5
>>> q[4]
5
>>> q[4] += 20
>>> q
{4: 25}
>>> d
{1: {2: {3: {4: 25}}}}
>>> q['foo'] = '99'
>>> q
{4: 25, 'foo': '99'}
>>> d
{1: {2: {3: {4: 25, 'foo': '99'}}}}
>>> 
https://en.xdnf.cn/q/70511.html

Related Q&A

Running tests against existing database using pytest-django

Does anybody know how to run Django Tests using pytest-django against an existing (e.g. production) database? I know that in general, this is not what unit tests are supposed to do, but in my case, I…

Python, Timeout of Try, Except Statement after X number of seconds?

Ive been searching on this but cant seem to find an exact answer (most get into more complicated things like multithreading, etc), I just want to do something like a Try, Except statement where if the …

MemoryError while pickling data in python

I am trying to dump a dictionary into pickle format, using dump command provided in python. The file size of the dictionary is around 150 mb, but an exception occurs when only 115 mb of the file is dum…

numpy dimensions

Im a newbie to Numpy and trying to understand the basic question of what is dimension,I tried the following commands and trying to understand why the ndim for last 2 arrays are same?>>> a= ar…

DataFrame Plot: how to sort X axis

I am plotting some counts from a field of dataframe (pandas) and I found that the X axis is sorted by the counts (descending order). Instead is it possible to sort by the alphabetical order of the fiel…

In-place custom object unpacking different behavior with __getitem__ python 3.5 vs python 3.6

a follow-up question on this question: i ran the code below on python 3.5 and python 3.6 - with very different results:class Container:KEYS = (a, b, c)def __init__(self, a=None, b=None, c=None):self.a …

Different ways of using __init__ for PyQt4

So... Im working on trying to move from basic Python to some GUI programming, using PyQt4. Im looking at a couple different books and tutorials, and they each seem to have a slightly different way of k…

Numpy: Reshape array along a specified axis

I have the following array:x = np.arange(24).reshape((2,3,2,2)) array([[[[ 0, 1],[ 2, 3]],[[ 4, 5],[ 6, 7]],[[ 8, 9],[10, 11]]],[[[12, 13],[14, 15]],[[16, 17],[18, 19]],[[20, 21],[22, 23]]]])I wou…

python suds wrong namespace prefix in SOAP request

I use python/suds to implement a client and I get wrong namespace prefixes in the sent SOAP header for a spefic type of parameters defined by element ref= in the wsdl. The .wsdl is referencing a data …

Allow help() to work on partial function object

Im trying to make sure running help() at the Python 2.7 REPL displays the __doc__ for a function that was wrapped with functools.partial. Currently running help() on a functools.partial function displ…