如果您的对象的顶层可以是一个列表(数组,在 JSON 术语中),那么您的输出格式将不起作用:例如["foo", "bar"]
,您会在逻辑上返回['[0]', '[1]']
,这可能不是您想要的。您还可以通过将对象名称传递给 FJ 的答案稍作修改来解决此问题:
def paths(container, name):
if isinstance(container, list):
for i, element in enumerate(container):
for path in paths(element, "%s[%d]" % (name, i)):
yield path
elif isinstance(container, dict):
for k, element in container.items():
for path in paths(element, "%s.%s" % (name, k)):
yield path
else:
yield name
用法:
>>> list(paths(x, "x"))
['x.a', 'x.b.c', 'x.d[0].e', 'x.d[0].f', 'x.d[1].e', 'x.d[1].f']
>>> list(paths(["foo", "bar"], "array"))
['array[0]', 'array[1]']
Python 3.3 引入了一种yield from
语法,使它更简洁:
def paths(container, name):
if isinstance(container, list):
for i, element in enumerate(container):
yield from paths(element, "%s[%d]" % (name, i))
elif isinstance(container, dict):
for k, element in container.items():
yield from paths(element, "%s.%s" % (name, k))
else:
yield name