Python将字符串解析为n深度字典

时间:2015-02-20 09:33:48

标签: python dictionary

我有一串键,用分隔符|分隔后跟一个值。

字符串可能是

key1|key2|key3=value

这应解析为

dct[key1][key2][key3] = value

个别词典可能已经存在。

为了开始原型,我已经硬编码了这样的字典的创建(字段是主字典 - 已经存在,s是由|(管道)分隔的键序列:

   keys=s.split('|')     
   if len(keys) == 1:
        fields[keys[0]] = field_data
   elif len(keys) == 2:
        if keys[0] not in fields:
            fields[keys[0]] = {}
        fields[keys[0]][keys[1]] = field_data

我将它扩展为三深度词典,但我知道它非常不优雅。

3 个答案:

答案 0 :(得分:2)

为什么需要三维字典?使用带有元组作为键的简单字典:

s = "key1|key2|key3=value"
ks, v = s.split("=")
dct = {}
dct[ks] = v

现在您可以像这样访问dct

print(dct[("key1", "key2", "key3")])

输出:

value

答案 1 :(得分:2)

例如,

s = "key1|key2|key3=value"

keys, value = s.split('=')
keys = keys.split('|')

base = {}

reduce(
    lambda d, k: d.setdefault(k, {}),
    keys[:-1],
    base
)[keys[-1]] = value

print base # {'key1': {'key2': {'key3': 'value'}}}

如果你经常需要这个,可能值得上课:

class NestedDict(dict):
    def __setitem__(self, key, value):
        if not isinstance(key, collections.Iterable) or isinstance(key, basestring):
            super(NestedDict, self).__setitem__(key, value)
            return
        keys = list(key)
        reduce(
            lambda d, k: d.setdefault(k, {}),
            keys[:-1],
            self
        )[keys[-1]] = value

然后:

s = "key1|key2|key3=value"
keys, value = s.split('=')

base = NestedDict()

base[keys.split('|')] = value

print base # {'key1': {'key2': {'key3': 'value'}}}

答案 2 :(得分:1)

这将假设您的键和值是字符串。即:

key1|key2|key3=value
dct['key1']['key2']['key3'] = 'value'
# The literal strings

然后你可以创建一个带字符串并将其拆分的函数。

def str_as_key(string, dictionary=None):
    dictionary = dictionary or {}
    keys = string.split("|")
    keys[-1:] = keys[-1].split("=")
    value = keys.pop()
    dicti = [dictionary, []]
    for key in keys:
        dicti = [dicti[0].get(key), dicti[1] + [key]]
        if not isinstance(dicti[0], dict):
            exec("dictionary['{0}'] = {1}; dicti[0] = {1}".format("']['".join(dicti[1]), '{}'))
    exec("dictionary['{}'] = '{}'".format("']['".join(keys), value))
    return dictionary

关于此方法的事情是它不必创建新的字典。它可以更新一个并保持其他键不变。 e.g:

>>> s = "key1|key2|key3=value"
>>> str_as_key(s, {})
{'key1': {'key2': {'key3': 'value'}}}
>>> str_as_key(s, {"key1": {"key2": 12, "foo": "bar"}, "pi": 3.14})
{'pi': 3.14, 'key1': {'foo': 'bar', 'key2': {'key3': 'value'}}}