【问题标题】:Python3 dictionary comprehension with sub-dictionary upacking?带有子字典升级的 Python3 字典理解?
【发布时间】:2019-02-11 18:27:43
【问题描述】:

假设有一本字典,root,它由键:值对组成,其中一些值本身就是字典。

是否可以(如果可以,如何)通过字典理解来解压这些子字典?

例如

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

示例:

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


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

【问题讨论】:

  • 导致了什么?你的预期输出是什么?
  • @DeepSpace 已更新以更清晰
  • {_k: _v for k,v in root.items() for _k, _v in (v if isinstance(v, dict) else {k: v}).items()}

标签: python python-3.x dictionary dictionary-comprehension iterable-unpacking


【解决方案1】:

我想我应该发布一个更广泛的解释来帮助你,因为它与其他现有问题有点不同

{
    _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
}

理解的关键部分是您需要一致且通用的逻辑才能使理解起作用。

您可以通过创建 dummy 嵌套字典来做到这一点,这些字典以前不存在使用 v if isinstance(v, dict) else {k: v}

那么这是一个简单的嵌套字典解包练习。

为了帮助您将来理解,我建议您将代码写出来,例如

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

并从这里向后工作

有用的参考资料

【讨论】:

    【解决方案2】:

    如果您有多层嵌套字典,我建议您使用以下基于递归函数的解决方案:

    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}
    

    【讨论】:

      【解决方案3】:

      这是一个递归解决方案。在函数_flatten_into_kv_pairs 中,我们遍历键和值对,如果值不是字典,则生成这些键/值。如果是,那么我们使用yield from 构造递归调用_flatten_into_kv_pairsflatten_dict 函数只是一个外壳,它将键/值对序列转换回字典。

      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))
      

      输出:

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2017-03-09
        • 2021-07-24
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-09-27
        • 2021-09-19
        相关资源
        最近更新 更多