Python 将字典树转换为多维列表
我有一本类似Python的字典:Python 将字典树转换为多维列表,python,dictionary,multidimensional-array,Python,Dictionary,Multidimensional Array,我有一本类似Python的字典: {'G': {'G': {'T': {'A': 'end'}, 'C': 'end'}, }, 'C': {'G': 'end'} } 如何将其转换为这样的多维数组 ['G', ['G', ['T', ['A'], 'C'] ], 'C', ['G'] ] 多谢各位 d = {
{'G':
{'G':
{'T':
{'A': 'end'},
'C': 'end'},
},
'C': {'G': 'end'}
}
如何将其转换为这样的多维数组
['G',
['G',
['T', ['A'],
'C']
],
'C', ['G']
]
多谢各位
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']]]]
还有一个变体:
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']]]]
首先,我假设您不关心字典中键的顺序,因为字典是无序的。如果您真的在意,那么除非您改用collections.OrderedDict或等效工具,否则没有解决方案可以完全满足您的需求 第二,尽管您现在使用字符串“end”作为sentinel值来指示处理应该停止的位置,但没有迹象表明我们应该对任何不是字典的值进行进一步处理。代码可以修改以适应其他类型的递归,但是现在我们将保持它的简单性,只需跳过树中的所有非字典值,尽管我们将处理它们的键 有了这些假设,我将使用一对递归函数来实现这一点。在本例中,编写了转换,以便您可以在需要时将这种模式与其他转换函数一起使用。转换的操作比列表理解要复杂一些,因为在某种意义上,我们将结果列表拼接到输出列表中,稍微平展输出
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';相应地更新代码。首先,我假设您不关心字典中键的顺序,因为字典是无序的。如果您真的在意,那么除非您改用collections.OrderedDict或等效工具,否则没有解决方案可以完全满足您的需求 第二,尽管您现在使用字符串“end”作为sentinel值来指示处理应该停止的位置,但没有迹象表明我们应该对任何不是字典的值进行进一步处理。代码可以修改以适应其他类型的递归,但是现在我们将保持它的简单性,只需跳过树中的所有非字典值,尽管我们将处理它们的键 有了这些假设,我将使用一对递归函数来实现这一点。在本例中,编写了转换,以便您可以在需要时将这种模式与其他转换函数一起使用。转换的操作比列表理解要复杂一些,因为在某种意义上,我们将结果列表拼接到输出列表中,稍微平展输出
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';相应地更新代码。如果“C”与dict中的G处于同一级别,为什么它在列表中不处于同一级别?我编辑了它,希望它现在有意义所有的“$”都发生了什么?您想要的输出不是有效的Python列表;支架不匹配。这是因为你在结尾忘了一个“],还是因为你[在开头]有一个额外的“?”很好的观点。我把它看作是一个额外的“?”[,但这种不一致性很重要。如果“C”与dict中的G处于同一级别,为什么它在列表中不处于同一级别?我编辑了它,希望它现在有意义所有的“$”都发生了什么?您想要的输出不是有效的Python列表;大括号不匹配。这是因为您最后忘记了a],还是因为您有一个额外的[一开始?很好,我把它当作额外的阅读[,但这种不一致性很明显。很接近,也许足够接近,但有两个差异:1我们假设顺序无关紧要;2结构有点不一致,因为上面写的相邻键是同一个列表的一部分;也就是说,根据您的顺序,Federico想要的答案是['C'、['G']、['G'、['G'、['C'、['t'、['a']]].在'A'和'C'下的子目录{'$':'$'}发生了什么事?我认为您的理解应该是:def treedct:return[[k]+treev if is instancev,dict else[k]for k,v in dct.items]哎呀,由于上面提到的不一致性,我的结构不太正确。我认为第二个变体更有意义。@dawg有问题,作者希望结果列表不带$,但我同意youClose,也许足够接近,但有两个差异:1我们假设顺序无关紧要;2结构有点不一致,如neiGhoring键写在上面是为了成为同一个列表的一部分;也就是说,按照您的顺序,Federico想要的答案是['C'、['G'、['G'、['C'、['T'、['A'\\\\\\\\\\].“'A'和'C'下的子目录{'$':'$}发生了什么事?我认为您的理解应该是:如果安装,返回[[k]+treev哎呀,由于上面提到的不一致性,我的结构不太正确。我认为第二个变体更有意义。@dawg有问题,作者希望结果列表不带$,但我同意你的看法,子目录{'$:'$}发生了什么事在‘A’和‘C’下?+1,但结果和问题一样有点不同mine@dawg正如我所认为的,它被拒绝了
我想应该是这样的。我将问题的预期结果解释为暗示{'$','$'}是一个哨兵值,用于指示停止递归的位置,尽管在本例中它似乎不是严格必需的。@npdu是的,我现在看到了。在'a'和'C'下的子命令{'$':'$}发生了什么事?+1,但结果和问题有点不同mine@dawg它被拒绝了,我认为它应该被拒绝。我将问题的预期结果解释为暗示{'$','$'}是一个指示停止递归的位置的哨兵值,尽管在本例中它似乎不是严格必需的。@npdu是的,我现在看到了。