Python pop()不会删除该项

时间:2012-08-01 20:50:44

标签: python-2.7

我正在开发一个将多级字典转换为一级字典列表的函数。

逻辑似乎是正确的。但是当我运行它时,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

2 个答案:

答案 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