1

マルチレベルの辞書を 1 レベルの辞書のリストに変換する関数に取り組んでいます。

ロジックは正しいようです。しかし、実行すると、while ループが無限に実行されます。初めてwhileループに入ったときに、機能していたことがわかりましたnext_level.pop()。while ループの 2 回目以降、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
4

2 に答える 2

1

辞書の例がなければ、視覚化するのは少し難しいです...しかし、一般的にこのような場合は、とにかく再帰をお勧めします:

def flatten( data ):
    output = []
    if ( isinstance(data, dict) ):
        output.append(data)
        for value in data.values():
            output += flatten(value)
    return output

あなたの質問への直接の答えでは、何が間違っているのか100%確信していません-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 = []

そして、何が起こるかを見てください。

于 2012-08-01T21:06:20.887 に答える
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
于 2012-08-01T21:21:07.737 に答える