首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >展平任意深度的二进制

展平任意深度的二进制
EN

Stack Overflow用户
提问于 2018-12-31 23:54:14
回答 2查看 96关注 0票数 4

我从另一个脚本收到一个字典,其中包含各种类型,特别是其他字典或列表,这些字典或列表可能包含其他字典作为值。

现在我要做的是创建一个单一的平面字典。键可能在封装的字典中出现多次。对我来说,最内部的关键字保存着最新的信息,所以我认为在消化“内部”字典时,dict.update是正确的例程。所谓“内部”词典,我指的是一本具有最外层词典某些价值的词典。

现在,我了解了如何将字典展平1级。我费了很大力气才能把它展平到任意多个级别。

我正在处理的字典类型的一个简单示例是:

代码语言:javascript
运行
复制
d = {1: {6: {7: {2: {'a'}}}}, 2: 'b', 3: {4: {2: 'c'}}, 5: ['a', 'b', {1: 'a'}]}

我的尝试在单层深度下工作正常:

代码语言:javascript
运行
复制
dd = dict()
for k, v in d.items():
    if isinstance(v, dict):
        dd.update(v)
    elif isinstance(v, list):
        for el in v:
            if isinstance(el, dict):
                dd.update(el)
        dd[k] = [el for el in v if not isinstance(el, dict)]
    else:
        dd[k] = v

这给了我:

代码语言:javascript
运行
复制
Out[56]:  {6: {7: {2: {'a'}}}, 2: 'b', 4: {2: 'c'}, 1: 'a', 5: ['a', 'b']}

它应该提供的是:

代码语言:javascript
运行
复制
{2: 'a', 5: ['a', 'b']}

注意键2'c'和not (我现在得到的) 'b'的值。这应该是因为键2的最内层值是'c',而不是'b'

我不只是想得到一个可以正常工作的代码(尽管这可以让我继续工作),我还想了解一下python是如何解决这样的问题的。我不得不承认我有点迷路了.

任何帮助都是非常感谢的!

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2019-01-01 00:06:33

您可以对生成器使用递归,并保留一个计数器来确定深度:

代码语言:javascript
运行
复制
d = {1: {6: {7: {2: {'a'}}}}, 2: 'b', 3: {4: {2: 'c'}}, 5: ['a', 'b', {1: 'a'}]}
def flatten(_d, _depth = 0):
  for a, b in _d.items():
     if isinstance(b, list):
       yield [a, [i for i in b if not isinstance(i, dict)], _depth]
       for c in b:
          if isinstance(c, dict):
             yield from flatten(c, _depth+1)
     elif isinstance(b, dict):
        yield from flatten(b, _depth+1)
     else:
        yield [a, b, _depth]

_result = {}
for a, b, c in flatten(d):
  if a not in _result:
     _result[a] = [b, c]
  else:
     if _result[a][-1] < c:
       _result[a] = [b, c]
print({a:b for a, [b, c] in _result.items()})

输出:

代码语言:javascript
运行
复制
{2: {'a'}, 5: ['a', 'b'], 1: 'a'}
票数 6
EN

Stack Overflow用户

发布于 2019-01-01 00:05:04

你的方法是正确的。但是您已经递归地更新了字典,以便它可以在任意数量的级别上工作

代码语言:javascript
运行
复制
def flatten(d):
    dd = dict()
    for k, v in d.items():
        if isinstance(v, dict):
            dd.update(flatten(v))
        elif isinstance(v, list):
            for el in v:
                if isinstance(el, dict):
                    dd.update(flatten(el))
            dd[k] = [el for el in v if not isinstance(el, dict)]
        else:
            dd[k] = v

    return dd

d = {1: {2: {'a'}}, 2: 'b', 3: {4: {2: 'c'}}, 5: ['a', 'b', {1: 'a'}]}
print flatten(d)
# {2: 'c', 1: 'a', 5: ['a', 'b']}
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/53989229

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档