我有一串键,用分隔符|
分隔后跟一个值。
字符串可能是
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
我将它扩展为三深度词典,但我知道它非常不优雅。
答案 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'}}}