2014-01-11 64 views
2

我有这样的(Python)的字典:转换树多维列表

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

我怎样才能将其转换为一个多维数组像这样的?:

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

谢谢

+0

如果'C'与字典中的G处于同一级别,为什么它不在列表中的同一级别? – aIKid

+0

我编辑它,并希望它现在有意义 –

+0

所有的'''''发生了什么? – Nabla

回答

2
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']]]] 
+0

关闭,也许关系不错,但有两个不同点:1)我们假设顺序无关紧要; 2)结构稍微偏离,因为相邻键被写在上面以成为同一列表的一部分;即你的订单,费德里科的理想答案是'['C',['G'],['G',['G',['C','T',['A']]]]] '。 –

+0

在“A”和“C”下的子字典'{'$':'$'}'发生了什么?我认为你的理解需要是:'def tree(dct):return [[k] + tree(v)if isinstance(v,dict)else [k] for k,v in dct.items()]' – dawg

+0

Oops ,由于上面提到的不一致,我的结构并不完全正确。我认为第二个变种更有意义。 –

2

首先,我假设你不关心字典中键的顺序,因为字典是无序的。如果你照顾,那么没有解决方案可以完成你想要的任务,除非你改用collections.OrderedDict或同等的方法。

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

有了这些假设,我会用递归的一对函数来做到这一点。在这一个中,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';相应地更新代码。

+0

在'A''和''C''下的子字典'{'$':'$'}是怎么回事? – dawg

+0

+1,但结果与问题有点不同,就像我的 – ndpu

+0

@dawg它被拒绝了,因为我认为它应该是。我将问题的理想结果解释为暗示{'$','$'}是一个标记值,用于指示停止递归的位置 - 虽然在本示例中它似乎不是绝对必要的。 –