在给定“路径”的情况下修改嵌套字典中的元素

Posted

技术标签:

【中文标题】在给定“路径”的情况下修改嵌套字典中的元素【英文标题】:Modify an element in a nested dict given a "path" to it 【发布时间】:2016-10-05 10:10:26 【问题描述】:

给定索引列表(任意长度)和嵌套 Python list/dict 对象的“路径”,我如何写入列表中的对象部分?

例如,这可能是我的对象(它是从 JSON 文件加载的):

data = "dogs":["tail": True, "properties":"test":1]

我的索引列表可能类似于 ["dogs", 0, "properties"]

如果我想检索路径中的值,我可以这样做:

>>> data = "dogs":["tail": True, "properties":"test":1]
>>> path = ["dogs", 0, "properties"]
>>> mydata = data
>>> for i in path:
...     mydata = mydata[i]
...
>>> mydata
'test': 1

但是说我想修改路径中的对象在整个结构中?上面的代码是按值传递,而不是通过引用,所以我认为我不能重用它。我能做什么?

【问题讨论】:

【参考方案1】:

这可能是一个不错的替代选择,但我发现 jsonpath-rw 库是在 JSON 结构中导航和搜索的好方法:

>>> from jsonpath_rw import jsonpath, parse
>>> 
>>> data = "dogs":["tail": True, "properties":"test":1]
>>> 
>>> jsonpath_expr = parse("dogs.[0].properties")
>>> jsonpath_expr.find(data)[0].value['test'] = 2
>>> print(data)
'dogs': ['tail': True, 'properties': 'test': 2]

请注意,您显示的代码中仍然存在“通过引用”行为:

>>> data = "dogs":["tail": True, "properties":"test":1]
>>> 
>>> path = ["dogs", 0, "properties"]
>>> mydata = data
>>> for i in path:
...     mydata = mydata[i]
... 
>>> mydata["test"] = 2
>>> print(data)
'dogs': ['tail': True, 'properties': 'test': 2]

【讨论】:

我不想引入外部依赖,但我会尝试您的第二个示例。 @LukeTaylor 是的,但请注意,将 mydata 分配给任何值都不会更新 data 字典。它只会“重新指向”mydata 变量。 啊,这行为很有趣 @LukeTaylor 好吧,虽然这是合乎逻辑的,mydata 是一种指向对象的“指针”,在我们的例子中,它位于 data 内部。如果我们通过mydata['test'] = 2 更新对象,我们会看到data 对象中反映的更改,因为mydata 是一个引用。但是,如果我们将 mydata 重新分配给其他东西,例如mydata = "new": "object"],我们只是将它重新指向一个新对象..希望它对你有意义。对不起,我不擅长解释事情:) 啊,我明白了。感谢您的额外解释。

以上是关于在给定“路径”的情况下修改嵌套字典中的元素的主要内容,如果未能解决你的问题,请参考以下文章

如何在给定完整路径的情况下导入模块?

在给定函数的情况下找到具有最小权重的路径

如何使用键路径从嵌套的字典dart中获取值。

如何使用键路径从嵌套的字典dart中获取值。

JS:如果沿嵌套字典路径为空,则返回默认值[重复]

更新嵌套对象 Firebase