简体   繁体   English

使用python中可能的字典列表展平嵌套字典

[英]Flattening nested dictionary with possible list of dictionaries in python

I have a nested (dictionaries) and (list of dictionaries) - parentheses for clarity - like the following: 我有一个嵌套的(词典)和(词典列表)-为了清楚起见,括号是-如下所示:

{"k": 
  {"hello": "bye",
   "hi": [{"a": "b", "c": "d"}, {"q": "I", "o": "p"}]
  }
}

And I want to flatten it into a path like the following: 我想将其展平为如下所示的路径:

"k/hello/bye/hi/a/b/c/d/q/I/o/p"

How can this be done? 如何才能做到这一点? There may be more layers of dictionaries (even within the ones in a list), so I need a very scalable solution. 词典可能有更多层(即使在列表中也是如此),因此我需要一个非常可扩展的解决方案。

Thanks, Jack 谢谢杰克

Recursive Solution 递归解

Recursion hardly ever works first run, guess I was lucky: 递归几乎从来没有运行过,我很幸运:

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

which gives: 这使:

'k/hello/bye/hi/a/b/c/d/q/I/o/p'

why? 为什么?

Each call to the traverse function takes a struct argument which can be either a dictionary, list, or string. traverse函数的每个调用都带有一个struct参数,该参数可以是字典,列表或字符串。

If it is a dictionary, we join together all the values followed by the result of traversing the corresponding keys. 如果它是字典,则我们将所有值连接在一起,然后再遍历相应键。 We then return this string. 然后,我们返回该字符串。

Similarly, if it a list, we join together the outputs of traversing all the elements and return the result. 同样,如果它是一个列表,我们将遍历所有元素的输出结合在一起并返回结果。

Finally, if the struct argument is just a string, we return it to our parent. 最后,如果struct参数只是一个字符串,我们将其返回给我们的父级。

In every case, each function is unaware of wear it is in the stack of calls, it just knows what its struct argument was and returns the correct response for that , argument. 在任何情况下,每一个功能不知道穿上它是在调用堆栈,它只是知道它的struct论点,并返回正确响应,论证。

This is what is so cool about recursion, you only need to consider one case, and as long as you write it correctly and pass the right things from parent to child, the result just emerges through cooperation. 对于递归来说,这是如此酷,您只需要考虑一种情况,只要您正确编写并从父母到孩子传递正确的东西,结果就可以通过合作得到。


NB As @DanielMeseko notes in the comments, dictionaries aren't ordered so, for instance, the hello an hi parts of the final string could "switch places" (along with their children trees). 注意:正如@DanielMeseko在评论中指出的那样,字典没有排序,例如, hello ,最后一个字符串的hi部分可以“切换位置”(以及子树)。


update 更新

To make the dictionaries sorted by the alphabetical position of the keys, we just need to use the sorted() function on the result from struct.items() . 要使字典按键的字母顺序排序,我们只需要对struct.items()的结果使用sorted()函数。

That is to stay: replace struct.items() in the above code with: 可以这样:将以上代码中的struct.items()替换为:

sorted(struct.items())

Which will sort alphabetically be default. 默认将按字母顺序排序。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM