python - 如何访问嵌套 json 对象的父级
问题描述
我有一个任意嵌套的 JSON 对象(使用 json.load 解析),由字典、列表、原语等组成。我首先使用递归遍历它并以 linux fs 格式跟踪节点的路径(对于列表,我附加 /元素到路径,因此在特定路径可以有多个对象),如下:
def traverse(node, path =''):
if isinstance(node, dict):
for key in node:
traverse(node[key], path+'/'+key)
elif isinstance(node, list):
for elem in node:
traverse(elem,path+'/element')
每个节点可能包含一个字符串,该字符串需要使用可以存在于树中任何位置的对象的值来填充,在当前节点的相对路径中引用,例如:“{../../key} {./child1 /child2/key}”。
问题:我可以访问当前节点的子节点的值,但不能直接访问当前节点的父节点。
我认为的解决方案:我认为的一种解决方案是拥有一个元组列表(子,父)并将当前节点与我要递归的子节点一起存储,然后在我需要向上时反向搜索该列表。这有点危险,因为如果孩子是原始值,那么它将等于任何其他具有相同值和类型的孩子,因此我可能会检索到错误的父母,但我认为反向遍历列表应该注意对吗?
我认为一个不同的解决方案是有一个字典,其中键是孩子的路径并重视父节点。我认为这应该会更好,因为唯一的时间路径冲突是列表元素,但它们都有相同的父元素,所以我认为应该没问题。
还有其他建议吗?或者对这两种解决方案有何评论?谢谢
解决方案
返回 dict 的父级(或任何没有反向指针的递归结构)的唯一方法是在遍历时记住它。
但请注意,您已经这样做了:您的path
字符串是从顶部到当前节点的路径。
让我们编写一个使用路径的函数:
def follow(head, path):
if not path:
return head
first, _, rest = path.partition('/')
return follow(head[first], rest)
当然,将它们构建path
为键元组而不是字符串可能会更好,因此我们不必将它们分开(因此我们不必担心如果任何键可能会转义或引用包含/
等);你总是join
可以在最后。
path
并且将其构建为节点(或键节点对)的元组而不只是键可能会更好,因此我们可以在恒定时间内访问父节点path[-1]
而不是在对数时间内访问父节点follow(head, path)
。但这实际上取决于您实际上要做什么;您的真实代码可能不只是遍历树,建立到每个节点的路径,然后对它们什么都不做。
然而,解决这个问题的一个非常好的方法是将遍历从里到外:制作traverse
一个迭代器:
def traverse(node, path =''):
if isinstance(node, dict):
for key in node:
yield from traverse(node[key], path+'/'+key)
elif isinstance(node, list):
for elem in node:
yield from traverse(elem,path+'/element')
yield (node, path)
现在我们可以循环traverse
执行任何我们想做的事,作为后序深度优先遍历:
for node, path in traverse(root):
# do something
现在您可以轻松地将其更改为 yield node, parent, path
(无论parent
是父节点,还是父键,或者您想要的任何东西)。
推荐阅读
- ruby-on-rails - Chrome 可以很好地连接到以“rails s”开头的 Rails 服务器,在系统规范期间因 ERR_CONNECTION_REFUSED 失败
- powerbi - Power BI Embedded - 是否有任何公共 ClientID、ClientSecret 和 TenantId 可用于实施“ServicePrincipal”的 App-Owns 场景
- python - 如何在抓取时提取嵌套值
- python - 如何访问和更改 Pygame.midi?
- c++ - 这个多线程列表处理代码有足够的同步吗?
- c - 如何在 Makefile 中包含数百个文件夹?
- typescript - 修复关于由 Webpack 加载器处理的导入的 TypeScript 警告?
- html - Css flex 左对齐和居中对齐
- python - “int”对象没有属性“pack”
- javascript - Shopify、formatMoney 动态使用当前货币