Posts: 11,859
Threads: 472
Joined: Sep 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
Posts: 2,344
Threads: 62
Joined: Sep 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)) ?
Posts: 11,859
Threads: 472
Joined: Sep 2016
OK, I'm listening, how exactly would you use this with the example?
Posts: 2,955
Threads: 48
Joined: Sep 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))
Posts: 11,859
Threads: 472
Joined: Sep 2016
Wavic, thenks for the reply. I understood using key, I'm not sure how to use the recursive lambda.
Posts: 2,344
Threads: 62
Joined: Sep 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.
Posts: 591
Threads: 26
Joined: Sep 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)
Posts: 11,859
Threads: 472
Joined: Sep 2016
Oct-09-2016, 12:43 AM
(This post was last modified: Oct-09-2016, 12:45 AM by Larz60+.)
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.
Posts: 591
Threads: 26
Joined: Sep 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.
Posts: 11,859
Threads: 472
Joined: Sep 2016
Oct-09-2016, 01:39 AM
(This post was last modified: Oct-09-2016, 01:41 AM by Larz60+.)
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
|