简体   繁体   English

Python3字典理解与子字典的困扰?

[英]Python3 dictionary comprehension with sub-dictionary upacking?

Suppose one has a dictionary, root which consists of key:value pairs, where some values are themselves dictionaries. 假设其中有一个字典,其root key:value对组成,其中一些值本身就是字典。

Can one (and if so, how) unpack these sub dictionaries via dictionary comprehension? 一个人(如果可以的话,如何)可以通过字典理解来解压这些子字典呢?

eg 例如

{k: v if type(v) is not dict else **v for k, v in root.items()}

example: 例:

root = {'a': 1, 'b': {'c': 2, 'd': 3}}


result = {'a': 1, 'c': 2, 'd': 3}

I guess I should post as an answer with a more broad explanation to help you as it is a little bit different to other existing questions 我想我应该发布一个带有更广泛解释的答案作为答案,以帮助您,因为它与其他现有问题有些不同

{
    _k: _v
    for k, v in root.items()
    for _k, _v in (         # here I create a dummy dictionary if non exists
                      v if isinstance(v, dict) else {k: v}
                  ).items() # and iterate that
}

The key part of understanding is that you need consistent and generic logic for the comprehension to work. 理解的关键部分是您需要一致且通用的逻辑才能理解。

You can do this by creating dummy nested dictionaries where they don't previously exist using v if isinstance(v, dict) else {k: v} 您可以通过创建虚拟嵌套字典来做到这一点, v if isinstance(v, dict) else {k: v}可以使用v if isinstance(v, dict) else {k: v}创建以前不存在的虚拟嵌套字典

Then this is a simple nested dictionary unpacking exercise. 然后,这是一个简单的嵌套字典解压缩练习。

To help in your future comprehensions I would recommend writing the code out eg 为了帮助您将来的理解,我建议编写代码,例如

res = dict()
for k,v in root.items():
    d = v if isinstance(v, dict) else {k: v}
    for _k, _v in d.items():
        res[_k] = _v

and work backwards from this 然后从这个倒退

Useful references 有用的参考

If you have several levels of nested dictionaries, I suggest you the following solution based on a recursive function: 如果您有多层嵌套字典,则建议您基于递归函数使用以下解决方案:

def flatten(res, root):
    for k,v in root.items():
        if isinstance(v, dict):
            flatten(res, v)
        else:
            res[k] = v

root = {'a': 1, 'b': {'c': 2, 'd': {'e': 5, 'f': 6}}}

result = {}
flatten(result, root)

print(result)  # {'a': 1, 'c': 2, 'e': 5, 'f': 6}

Here is a recursive solution. 这是一个递归解决方案。 In the function _flatten_into_kv_pairs , we iterate through the key and values pair and yield those keys/values if the value is a not a dictionary. 在函数_flatten_into_kv_pairs ,我们迭代键和值对,如果值不是字典,则产生这些键/值。 If it is, then we recursively call _flatten_into_kv_pairs with the yield from construct. 如果是,那么我们递归地调用_flatten_into_kv_pairsyield from construct的yield from The function flatten_dict is just a shell which turns sequence of key/value pairs back into a dictionary. 函数flatten_dict只是一个shell,它将键/值对的序列转换回字典。

def _flatten_into_kv_pairs(dict_object):
    for k, v in dict_object.items():
        if isinstance(v, dict):
            yield from _flatten_into_kv_pairs(v)
        else:
            yield k, v


def flatten_dict(dict_object):
    return dict(_flatten_into_kv_pairs(dict_object))


root = {'a': 1, 'b': {'c': 2, 'd': 3, 'e': {'f': 4, 'g': 5}}}
print(flatten_dict(root))

Output: 输出:

{'a': 1, 'c': 2, 'd': 3, 'f': 4, 'g': 5}

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

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