我正在开发一个将多级字典转换为一级字典列表的函数。
逻辑似乎是正确的。但是当我运行它时,while循环运行无穷大。我发现它第一次进入while循环时,next_level.pop()
正在运行。从while循环的第二次开始,pop()
函数永远不会删除next_level
的最后一项。我还尝试按next_level[-1]
检索最后一项,并按del next_level[-1]
删除最后一项。但结果是一样的。我认为它可能与参考事物有关。有什么想法吗?
def flat_dict(self, params):
"""convert a multi-level dictionary to a list of one-level dictionaries"""
plist = next_level = []
next_level.append(params)
while next_level:
current_level = temp_level = next_level.pop()
for k, v in current_level.iteritems():
if isinstance(v, dict):
next_level.append(temp_level.pop(k))
pk = [x for x in next_level[-1].keys() if x.endswith('_id')]
temp_level[pk[0]] = next_level[-1][pk[0]]
plist.append(temp_level)
return plist
答案 0 :(得分:1)
没有字典的例子,它有点难以想象......但通常对于这样的情况,我还是建议递归:
def flatten( data ):
output = []
if ( isinstance(data, dict) ):
output.append(data)
for value in data.values():
output += flatten(value)
return output
直接回答你的问题,我不是百分之百确定出了什么问题 - 我可以说pop()本身就可以了。我猜它与初始化plist的方式有关,你是否得到了无限循环?
plist = next_level = []
这一行实际上是将plist和next_level设置为相同的列表 - 没有为每个变量初始化一个空白列表。
>>> plist = next_level = []
>>> plist.append(1)
>>> next_level
[1]
当您修改plist时,稍后在循环中,您实际上也在修改next_level,这不是我想要的...尝试以这种方式定义plist / next_level:
plist = []
next_level = []
看看会发生什么。
答案 1 :(得分:0)
我并不完全明白你要做什么,所以我认为这个答案并不是你所需要的。但也许你可以用它作为解决方案的开始。
这个答案不会使dict
变得扁平;它只是遍历它并构建一个新的dict
实例列表。它以递归方式调用自己来展平任意嵌套的dict
。
def flat_dict(self, d_to_flatten, lst_flat=None):
"""convert a multi-level dictionary to a list of one-level dictionaries"""
if lst_flat is None:
lst_flat = []
d = {}
lst = []
for k, v in d_to_flatten.iteritems():
if isinstance(v, dict):
lst.append(v)
else:
d[k] = v
lst_flat.append(d)
for d in lst:
flat_dict(self, d, lst_flat)
return lst_flat