Python Forum
Dynamic Allocation of Nested Dictionaries - Printable Version

+- Python Forum (https://python-forum.io)
+-- Forum: General (https://python-forum.io/forum-1.html)
+--- Forum: Code sharing (https://python-forum.io/forum-5.html)
+--- Thread: Dynamic Allocation of Nested Dictionaries (/thread-381.html)

Pages: 1 2


Dynamic Allocation of Nested Dictionaries - Larz60+ - Oct-08-2016

Hello,

Here's a class for dynamically allocating a dictionary with an example
"""
Dynamic nested dictionary
Author: Larz60+
"""
#
import collections


class DynamicNestedDict:
    def dynamic_nested_dict(self):
        return collections.defaultdict(self.dynamic_nested_dict)


# Example of usage
if __name__ == '__main__':
    keylist = ['bind', 'application level', 'binding']
    loc = [20, 96, 100, 101, 102, 104, 105, 115, 193, 434, 546]

    dd = DynamicNestedDict()
    ddict = dd.dynamic_nested_dict()

    x = 'ddict'
    for n in range(len(keylist)):
        x = '{}[{}]'.format(x, repr(keylist[n]))
    x = x + ' = loc'
    exec(x)

    print("ddict['bind']['application level']['binding']: {}"
          .format(ddict['bind']['application level']['binding']))
Any improvements appreciated


RE: Dynamic Allocation of Nested Dictionaries - micseydel - Oct-08-2016

Why the range(len()) instead of a regular for loop? Including some output would be helpful here, even refactored, that loop is pretty confusing.

Why is this a class with a method instead of a function? This API seems to have extra to it which is unnecessary.

Also, is it any better than
DynamicNestedDict = lambda: defaultdict(lambda: defaultdict(DynamicNestedDict))
?


RE: Dynamic Allocation of Nested Dictionaries - Larz60+ - Oct-08-2016

OK, I'm listening, how exactly would you use this with the example?


RE: Dynamic Allocation of Nested Dictionaries - wavic - Oct-08-2016

(Oct-08-2016, 12:39 PM)Larz60+ Wrote:     
for n in range(len(keylist)):
        x = '{}[{}]'.format(x, repr(keylist[n]))
I think this can be translated to
for key in keylist:
    x = '{}[{}]'.format(x, repr(key))



RE: Dynamic Allocation of Nested Dictionaries - Larz60+ - Oct-09-2016

Wavic, thenks for the reply. I understood using key, I'm not sure how to use the recursive lambda.


RE: Dynamic Allocation of Nested Dictionaries - micseydel - Oct-09-2016

(Oct-08-2016, 10:23 PM)Larz60+ Wrote: OK, I'm listening, how exactly would you use this with the example?
>>> import collections
>>> DynamicNestedDict = lambda: collections.defaultdict(lambda: collections.defaultdict(DynamicNestedDict))
>>> dd2 = DynamicNestedDict()
>>> dd2['bind']['application level']['binding'] = "anything"
>>> print dd2['bind']['application level']['binding']
anything
If I'm oversimplifying, let me know, and I'll see if I can accommodate the complication.


RE: Dynamic Allocation of Nested Dictionaries - Mekire - Oct-09-2016

(Oct-09-2016, 12:05 AM)Larz60+ Wrote:  I understood using key, I'm not sure how to use the recursive lambda.

Also, remember that nothing is special about lambda... should be equivalent to the following:
def DynamicNestedDict():
    def internal():
        return defaultdict(DynamicNestedDict)
    return defaultdict(internal)



RE: Dynamic Allocation of Nested Dictionaries - Larz60+ - Oct-09-2016

Micseydel - Thanks i like it -- a lot --

Now I expect that I will still have to use exec when building the keys from a list as in my example.


RE: Dynamic Allocation of Nested Dictionaries - Mekire - Oct-09-2016

Quote:Now I expect that I will still have to use exec when building the keys from a list as in my example.
I was just wondering about that actually.
I know how to create slice objects programatically with the slice built-in, but not how to construct a series of indices of unknown size.

You certainly don't need to use exec but I am struggling to think of a particularly clean way to do it:
level = ddict
while keylist:
    key = keylist.pop(0)
    if not keylist:
        level[key] = value
    else:
        level = level[key]
Pretty damn ugly.  Gotta be a better way.


RE: Dynamic Allocation of Nested Dictionaries - Larz60+ - Oct-09-2016

Here's the improved code:

import collections


def try_dynamic_nested_dict():
    keylist = ['bind', 'application level', 'binding']
    loc = [20, 96, 100, 101, 102, 104, 105, 115, 193, 434, 546]

    DynamicNestedDict = lambda: collections.defaultdict(lambda: collections.defaultdict(DynamicNestedDict))

    dd = DynamicNestedDict()
    x = 'dd'

    for key in keylist:
        x = '{}[{}]'.format(x, repr(key))

    x += ' = loc'
    exec(x)

    print("dd['bind']['application level']['binding']: {}"
          .format(dd['bind']['application level']['binding']))


if __name__ == '__main__':
    try_dynamic_nested_dict()
results:
dd['bind']['application level']['binding']: [20, 96, 100, 101, 102, 104, 105, 115, 193, 434, 546]
Thanks guys