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

Luk*_*lor 4 python dictionary nested pass-by-reference pass-by-value

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

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

data = {"dogs":[{"tail": True, "properties":{"test":1}}]}
Run Code Online (Sandbox Code Playgroud)

我的索引列表可能看起来像["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}
Run Code Online (Sandbox Code Playgroud)

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

ale*_*cxe 5

这可能是一个不错的替代选择,但我发现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}}]}
Run Code Online (Sandbox Code Playgroud)

请注意,您在显示的代码中仍然具有“按引用”行为:

>>> 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}}]}
Run Code Online (Sandbox Code Playgroud)

  • @LukeTaylor 好吧,虽然它是合乎逻辑的,`mydata` 是一种指向对象的“指针”,在我们的例子中它位于 `data` 内。如果我们通过 `mydata['test'] = 2` 更新对象,我们会看到变化反映在 `data` 对象中,因为 `mydata` 是一个引用。但是,如果我们将 `mydata` 重新分配给其他东西,例如 `mydata = {"new": "object"]`,我们只是将它重新指向一个新对象......希望它对你有意义。对不起,我在解释事情方面很糟糕:) (2认同)