How can I split a string and form a multi-level nested dictionary?

I have a line like

foo/bar/baz 

I also have val=1 , for example. Is there a clean way to split foo/bar/baz into a multidimensional dict with the last element in the dict equal to 1. So it will look like

 {'foo': {'bar': {'baz': 1}}} 
+8
python string dictionary
source share
2 answers

You can use reduce and reversed functions like this

 >>> reduce(lambda res, cur: {cur: res}, reversed("foo/bar/baz".split("/")), 1) {'foo': {'bar': {'baz': 1}}} 

If you are using Python 3.x, you need to import reduce from functools

 >>> from functools import reduce >>> reduce(lambda res, cur: {cur: res}, reversed("foo/bar/baz".split("/")), 1) {'foo': {'bar': {'baz': 1}}} 

Here, the last argument to reduce is the initial value. It will take values ​​one by one from the iteration passed, call the function with the result and the current value, and then next time, the last result will be the first argument, and the current value will be the second argument. When the iterable is exhausted, it will return the result.

So, execution would be step by step as shown below

Let's say func is a lambda function, and it is called so many times

 func(1, "baz") => {"baz": 1} func({"baz": 1}, "bar") => {"bar": {"baz": 1}} func({"bar": {"baz": 1}}, "foo") => {"foo": {"bar": {"baz": 1}}} 
+7
source share
 d = 1 for part in reversed(s.split('/')): d = {part: d} 

If you need to expand this to create something like a directory tree, you may need a solution based on defaultdict :

 import collections def tree(): return collections.defaultdict(tree) def parsetree(path_strings): t = tree() for s in path_strings: temp = t parts = s.split('/') for part in parts[:-1]: temp = temp[part] temp[parts[-1]] = 1 return t 

Demo:

 >>> t = parsetree([ ... 'foo/bar/baz', ... 'foo/bar/bop', ... 'foo/spam' ... ]) >>> t['foo']['bar']['baz'] 1 >>> t['foo']['spam'] 1 
+2
source share

All Articles