【问题标题】:Convert tree of dictionaries to multidimensional list [closed]将字典树转换为多维列表 [关闭]
【发布时间】:2014-01-30 14:33:14
【问题描述】:

我有一本这样的字典(Python):

{'G': 
     {'G': 
          {'T': 
               {'A': 'end'},
          'C': 'end'},
     }, 
 'C': {'G': 'end'}
}

如何将其转换为像这样的多维数组?:

['G', 
      ['G', 
          ['T', ['A'],
           'C']
       ], 
  'C', ['G'] 
]

谢谢

【问题讨论】:

  • 如果'C'在dict中与G在同一级别,为什么它不在列表中的同一级别?
  • 我编辑了它,希望它现在有意义
  • '$' 发生了什么事?
  • 您想要的输出不是有效的 Python 列表;大括号不匹配。这是因为您忘记了末尾的],还是因为您在开头多出了一个[?
  • 好点。我把它读成了一个额外的[,但这种不一致很严重。

标签: python dictionary multidimensional-array


【解决方案1】:
d = {
 'G': 
     {'G': 
          {'T': 
               {'A': {'$': '$'}},
          'C': {'$': '$'}}
     }, 
 'C': {'G': {'$': '$'}}
}

def merge(dct):
    return [[k] + merge(v) for k,v in dct.items() if isinstance(v, dict)]

>>> merge(d)
[['C', ['G']], ['G', ['G', ['C'], ['T', ['A']]]]]

另一个变种:

def merge(dct):
    l = []
    for k,v in dct.items():
        if isinstance(v, dict):
            l.append(k)
            m = merge(v)
            if m:
                l.append(m)
    return l


>>> merge(d)
['C', ['G'], 'G', ['G', ['C', 'T', ['A']]]]

【讨论】:

  • 关闭,也许足够接近,但有两个差异:1)我们假设顺序无关紧要; 2)结构有点偏离,因为上面写的相邻键是同一个列表的一部分;即,根据您的订单,Federico 想要的答案是 ['C', ['G'], ['G', ['G', ['C', 'T', ['A']]]]]。
  • 'A' 和 'C' 下的子字典 {'$': '$'} 发生了什么?我认为你的理解需要是:def tree(dct): return [[k] + tree(v) if isinstance(v, dict) else [k] for k,v in dct.items()]
  • 糟糕,由于上面提到的不一致,我的结构不太正确。我认为第二种变体更有意义。
  • @dawg 有问题,作者想要不带 $ 的结果列表,但我同意你的看法
【解决方案2】:

首先,我假设您不关心字典中键的顺序,因为字典是无序的。如果您确实在意,那么除非您改用 collections.OrderedDict 或同等功能,否则没有任何解决方案可以满足您的需求。

其次,虽然您现在使用字符串 'end' 作为标记值来指示处理应该停止的位置,但没有迹象表明我们应该对不是字典的 any 值进行任何进一步处理.可以修改代码以适应其他类型的递归,但现在我们将使其保持简单,并跳过树中的所有非字典值(尽管我们将处理它们的键)。

有了这些假设,我会用一对递归函数来做到这一点。在这一个中,编写了transform,以便您可以根据需要将这种模式与其他转换函数一起使用。 transform 的操作比列表推导复杂一点,因为我们将结果列表拼接到输出列表中——从某种意义上说,稍微“扁平化”了输出。

d = {
    'G': {'G': 
            {'T': 
                {'A': 'end'},
             'C': 'end'}
         }, 
    'C': {'G': 'end'}
}

# Transform a dictionary to a list using the given transformation function.
# The transformation function must take a key and value and return a sequence,
# which will be spliced into the output list. No ordering is imposed on the
# keys of the dictionary.
def transform(d, f):
    out = []
    for k, v in d.iteritems():
        out.extend(f(k, v))
    return out

def nested_dict_to_list(key, value):
    if not isinstance(value, dict):
        # don't recurse into this value
        return [key]
    else:
        return [key, transform(value, nested_dict_to_list)]


>>> transform(d, nested_dict_to_list)
['C', ['G'], 'G', ['G', ['C', 'T', ['A']]]]

已编辑:问题之前使用{'$': '$'}作为标记值,​​现在简单使用'end';相应地更新代码。

【讨论】:

  • 'A' 和 'C' 下的子字典 {'$': '$'} 发生了什么?
  • +1,但结果和我的问题有点不同
  • @dawg 它被拒绝了,我认为它应该被拒绝。我将问题的预期结果解释为暗示 {'$', '$'} 是一个标记值,用于指示停止递归的位置——尽管在此示例中它似乎不是绝对必要的。
  • @npdu 是的,我现在看到了。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-18
  • 2019-09-17
  • 2022-10-16
  • 2017-09-12
  • 2021-02-04
相关资源
最近更新 更多