我有一个嵌套的(词典)和(词典列表)-为清楚起见,用括号括起来,如下所示:
{"k":
{"hello": "bye",
"hi": [{"a": "b", "c": "d"}, {"q": "I", "o": "p"}]
}
}
我想将其展平为如下所示的路径:
"k/hello/bye/hi/a/b/c/d/q/I/o/p"
这怎么办?词典可能有更多层(甚至在列表中也是如此),所以我需要一个非常可扩展的解决方案。
谢谢, 杰克
答案 0 :(得分:4)
递归几乎从未运行过,我很幸运:
def traverse(struct):
if isinstance(struct, dict):
return '/'.join(k+'/'+traverse(v) for k,v in struct.items())
elif isinstance(struct, list):
return '/'.join(traverse(v) for v in struct)
else:
return struct
给出:
'k/hello/bye/hi/a/b/c/d/q/I/o/p'
为什么?
每次对traverse
函数的调用都带有一个struct
参数,该参数可以是字典,列表或字符串。
如果它是字典,则我们将所有值连接在一起,然后遍历相应键。然后,我们返回该字符串。
类似地,如果它是一个列表,我们将遍历所有元素的输出结合在一起并返回结果。
最后,如果struct
参数只是一个字符串,我们将其返回给父对象。
在每种情况下,每个函数都不知道它在调用堆栈中是否磨损,它只知道其struct
参数是什么,并为参数那个返回正确的响应。
这就是递归的奇妙之处,您只需要考虑一种情况,只要编写正确,并将正确的东西从父母传递给孩子,结果就可以通过合作得出。
正如@DanielMeseko
在评论中指出的那样,字典没有顺序,例如,最终字符串的hello
和hi
部分可能会“切换位置”(及其子树)
更新
要使字典按键的字母顺序排序,我们只需要对sorted()
的结果使用struct.items()
函数。
这将保持不变:将以上代码中的struct.items()
替换为:
sorted(struct.items())
默认按字母顺序排序。