Python 设置字典嵌套键与点划定字符串



如果我有一个嵌套的字典,并且我传入一个像"key1.key2.key3"这样的字符串,它将转换为:

myDict["key1"]["key2"]["key3"]

能够有一个方法,我可以传递该字符串并将其转换为该键分配,这是一种优雅的方法?类似的东西myDict.set_nested('key1.key2.key3', someValue)

仅使用内置内容:

def set(my_dict, key_string, value):
"""Given `foo`, 'key1.key2.key3', 'something', set foo['key1']['key2']['key3'] = 'something'"""
# Start off pointing at the original dictionary that was passed in.
here = my_dict
# Turn the string of key names into a list of strings.
keys = key_string.split(".")
# For every key *before* the last one, we concentrate on navigating through the dictionary.
for key in keys[:-1]:
# Try to find here[key]. If it doesn't exist, create it with an empty dictionary. Then,
# update our `here` pointer to refer to the thing we just found (or created).
here = here.setdefault(key, {})
# Finally, set the final key to the given value
here[keys[-1]] = value

myDict = {}
set(myDict, "key1.key2.key3", "some_value")
assert myDict == {"key1": {"key2": {"key3": "some_value"}}}

这将一次遍历一个键myDict确保每个子键都引用嵌套字典。

您也可以递归解决此问题,但是您可能会冒递归错误异常而没有任何实际好处的风险。

有许多现有的模块已经可以做到这一点,或者非常类似的东西。 例如,jmespath 模块将解析 jmespath 表达式,因此:

>>> mydict={'key1': {'key2': {'key3': 'value'}}}

您可以运行:

>>> import jmespath
>>> jmespath.search('key1.key2.key3', mydict)
'value'

jsonpointer 模块做类似的事情,尽管它喜欢/分隔符而不是.

考虑到预先存在的模块的数量,我将避免尝试编写自己的代码来执行此操作。

编辑:OP的澄清清楚地表明,这个答案不是他想要的。我把它留在这里给那些通过标题找到它的人。


不久前我实现了一个这样做的类......它应该服务于您的目的。 我通过覆盖对象的默认 getattr/setattr 函数来实现这一点。

看看吧!AndroxxTraxxon/cfgutils

这使您可以执行一些代码,如下所示...

from cfgutils import obj
a = obj({
"b": 123,
"c": "apple",
"d": {
"e": "nested dictionary value"
}
})
print(a.d.e)
>>> nested dictionary value

相关内容

  • 没有找到相关文章

最新更新