Python 将具有混合值的dict转换为平面dict
我想迭代一个dict,它的值是列表、unicode字符串、dict、bools和int的混合体,以生成一个具有所有键值对的一维dict。我不想保留关联值为dict的键 我尝试了一个递归函数,但遗漏了一些步骤。也许我需要在某个地方使用Python 将具有混合值的dict转换为平面dict,python,recursion,iteration,Python,Recursion,Iteration,我想迭代一个dict,它的值是列表、unicode字符串、dict、bools和int的混合体,以生成一个具有所有键值对的一维dict。我不想保留关联值为dict的键 我尝试了一个递归函数,但遗漏了一些步骤。也许我需要在某个地方使用.update()或+= def unravel(data): resultsdict = {} for k in data: if isinstance(data[k],dict): unravel(data[
.update()
或+=
def unravel(data):
resultsdict = {}
for k in data:
if isinstance(data[k],dict):
unravel(data[k])
else:
resultsdict[k] = data[k]
我的顶级dict值示例:
<type 'list'>
<type 'bool'>
<type 'dict'>
<type 'unicode'>
<type 'bool'>
<type 'unicode'>
<type 'dict'>
<type 'int'>
<type 'unicode'>
您的方法
unravel
每次递归调用时都会创建一个resultsdict
的新实例。因此,并非所有数据都进入主词典(可以这么说)。请尝试以下方法:
def unravel(data, resultsdict={}):
for k in data:
if isinstance(data[k],dict):
unravel(data[k], resultsdict)
else:
resultsdict[k] = data[k]
return resultsdict
在类似这样的递归场景中,每次递归时都应该随身携带可变数据结构。您的方法
unravel
每次递归调用时都会创建resultsdict
的新实例。因此,并非所有数据都进入主词典(可以这么说)。请尝试以下方法:
def unravel(data, resultsdict={}):
for k in data:
if isinstance(data[k],dict):
unravel(data[k], resultsdict)
else:
resultsdict[k] = data[k]
return resultsdict
在类似这样的递归场景中,每次递归时都应该随身携带可变数据结构。您几乎就到了,但需要返回创建的字典,并使用递归调用返回的值更新字典:
def unravel (data):
d = {}
for k, v in data.items():
if isinstance(v, dict):
d.update(unravel(v))
else:
d[k] = v
return d
这样使用:
>>> unravel({ 'a': { 'b': 'c', 'd': 'e' }, 'f': 'g', 'h': { 'i': 'j' } })
{'f': 'g', 'i': 'j', 'b': 'c', 'd': 'e'}
您就快到了,但需要返回创建的字典,并使用递归调用返回的值更新字典:
def unravel (data):
d = {}
for k, v in data.items():
if isinstance(v, dict):
d.update(unravel(v))
else:
d[k] = v
return d
这样使用:
>>> unravel({ 'a': { 'b': 'c', 'd': 'e' }, 'f': 'g', 'h': { 'i': 'j' } })
{'f': 'g', 'i': 'j', 'b': 'c', 'd': 'e'}
你可以把字典里所有的元组都解包,然后把整个东西都展平
# Turn every key,value pair into a list of tuples
# [(key, value)] if it's any datatype but dict
# value.iteritems() otherwise
grouped_key_value_pairs = [v.iteritems() if isinstance(v,dict) else [(k,v)] for k,v in data.iteritems()]
# Flatten into a single list of tuples and turn into dict!
result = dict([kv_pair for group in all_kv_pairs for kv_pair in group])
你可以把字典里所有的元组都解包,然后把整个东西都展平
# Turn every key,value pair into a list of tuples
# [(key, value)] if it's any datatype but dict
# value.iteritems() otherwise
grouped_key_value_pairs = [v.iteritems() if isinstance(v,dict) else [(k,v)] for k,v in data.iteritems()]
# Flatten into a single list of tuples and turn into dict!
result = dict([kv_pair for group in all_kv_pairs for kv_pair in group])
似乎每次使用这个递归函数时,都会用resultsdict={}重置字典。我认为这可能是一个问题?因此,对于包含在您的dict中的每一个其他dict,您希望将该dict的内容移动到您的结构的根级别吗?例如,
{'a':{'b':'c'},'d':'E'}
变成{'b':'c','d':'E'}
correct@Adib同样正确的是,也许我应该使用yield
?似乎每次使用这个递归函数时,都会使用resultsdict={}重置字典。我认为这可能是一个问题?因此,对于包含在您的dict中的每一个其他dict,您希望将该dict的内容移动到您的结构的根级别吗?例如,{'a':{'b':'c'},'d':'E'}
变成{'b':'c','d':'E'}
correct@Adib同样正确,也许我应该使用yield
?请避免,即使您没有在此处对其进行实际变异。实际上,我没有看到该编辑。现在它只是坏了。尝试展开({'a':'b'})
然后是展开({'b':'c'})
。后者将返回{'a':'b','b':'c'}
现在。我喜欢你的解决方案:不客气。我很高兴你选择了poke的答案。这是现场:)请避免,即使你实际上没有在这里变异它。事实上,我没有看到编辑。现在它只是坏了。尝试展开({'a':'b'})
然后是展开({'b':'c'})
。后者将返回{'a':'b','b':'c'}
现在。我喜欢你的解决方案:不客气。我很高兴你选择了poke的答案。这是现场:)添加了一些评论试图帮助,但我确实认为这是一个相当密集的列表理解,我确实喜欢一个很好的一行。。我肯定会把你的解决方案放在我的银行里,并添加一些评论来帮助你,但我确实认为这是一个相当密集的列表理解,尽管我很喜欢一行。。我一定会把你的解决方案存入我的银行