将列表转换为嵌套字典

时间:2011-07-14 06:57:23

标签: python list dictionary

例如我有

x = ['a','b','c']

我需要将其转换为:

y['a']['b']['c'] = ''

这可能吗?

对于后台,我有一个配置文件,其中包含指向某些json数据中某个位置的点符号。我想使用带点的符号字符串来访问json文件中的特定数据。例如,在config:

path_to_data = "user.name.first_name"

我希望我的脚本能够识别为:

json_data["user"]["name"]["first_name"]

所以我可以得到first_name字段的值。我将原始字符串转换为列表,现在我不知道如何将其转换为嵌套字典。

编辑:我需要应用dict的现有数据结构。让我们说:

m = {'a': {'b': {'c': 'lolcat'}}}

这样

m['a']['b']['c']

给了我'lolcat'。如果我得到了正确的字典结构(正如一些回复所做的那样),我仍然需要将它应用于现有字典'm'。

所以,我再次从配置文件中得到这个:

c = 'a.b.c'

我转换为一个列表,认为这会使事情变得更容易:

x = ['a','b','c']

现在我有一个类似json的数据结构:

m = {'a': {'b': {'c': 'lolcat'}}}

因此,从'x'生成的嵌套字典应该能够遍历'm'以便

m['a']['b']['c']

让我成为猫。

6 个答案:

答案 0 :(得分:5)

li = ['a','b','c']

d = reduce(lambda x, y: {y:x}, reversed(li+['']))

print(d)
print(d['a']['b']['c'])

答案 1 :(得分:4)

我猜你最后也希望包含一个值。这也适用于此:

def get_value(d, l):
    if len(l) > 1:
        return get_value(d[l[0]], l[1:])
    return d[l[0]]

def add_keys(d, l, c=None):
    if len(l) > 1:
        d[l[0]] = _d = {}
        d[l[0]] = d.get(l[0], {})
        add_keys(d[l[0]], l[1:], c)
    else:
        d[l[0]] = c

def main():
    d = {}
    l1 = ['a', 'b', 'c', 'd']
    c1 = 'letters'
    l2 = [42, "42", (42,)]
    c2 = 42
    add_keys(d, l1, c1)
    print d
    add_keys(d, l2, c2)
    print d

if __name__ == '__main__':
    main()

打印:

{'a': {'b': {'c': {'d': 'letters'}}}}
{'a': {'b': {'c': {'d': 'letters'}}}, 42: {'42': {(42,): 42}}}
letters
42

所以它肯定有效。获胜的递归。

答案 2 :(得分:1)

>>> x = ['a','b','c']
>>> y={}
>>> y[x[-1]]=""
>>> x.pop(-1)
'c'
>>> for i in x[::-1]:
...     y={i:y}
...
>>> y
{'a': {'b': {'c': ''}}}
>>> y['a']['b']['c']
''

答案 3 :(得分:0)

这样可行。

#!/usr/bin/python2
from __future__ import print_function

x = ['a','b','c']

def ltod(l):
    rv = d = {}
    while l:
        i = l.pop(0)
        d[i] = {}
        d = d[i]
    return rv

d = ltod(x)
print(d)
print(d["a"]["b"]["c"])
d["a"]["b"]["c"] = "text"
print(d["a"]["b"]["c"])

输出:

{'a': {'b': {'c': {}}}}
{}
text

答案 4 :(得分:0)

查找下面不太漂亮但非常简单的样本:

path_to_data = "user.name.first_name"
keys = path_to_data.split('.')
t = []
for key in keys[::-1]: # just to iterate in reversed order
    if not t:
        t.append({k:{}})
    else:
        t[-1] = ({k: t[-1]})
#t[0] will contain your dictionary

答案 5 :(得分:0)

一般解决方案是使用collections.defaultdict创建嵌套字典。然后覆盖__setitem__,无论您喜欢什么行为。此示例也将执行字符串解析。

from collections import defaultdict

class nesteddict(defaultdict):
    def __init__(self):
        defaultdict.__init__(self, nesteddict)
    def __setitem__(self, key, value):
        keys = key.split('.')
        for key in keys[:-1]:
            self = self[key]
        defaultdict.__setitem__(self, keys[-1], value)

nd = nesteddict()
nd['a.b.c'] = 'lolcat'
assert nd['a']['b']['c'] == 'lolcat'