2016-04-12 15 views
1

値をリスト、Unicode文字列、dicts、bool、intの混合ですべてのキーと値のペアを持つ1次元のdictを生成するdictを繰り返したい。私は関連する値が辞書であるキーを保持することには気をつけません。dictを混合値でフラットなdictに変換する

再帰関数を試しましたが、いくつかの手順がありません。おそらく私は.update()または+=をどこかで使う必要がありますか?私のトップレベルの辞書の値の

def unravel(data): 
    resultsdict = {} 
    for k in data: 
     if isinstance(data[k],dict): 
      unravel(data[k]) 
     else: 
      resultsdict[k] = data[k] 

例:

<type 'list'> 
<type 'bool'> 
<type 'dict'> 
<type 'unicode'> 
<type 'bool'> 
<type 'unicode'> 
<type 'dict'> 
<type 'int'> 
<type 'unicode'> 
+0

あなたがダイビングするたびに表示されますこの再帰関数には、resultsdict = {}で辞書をリセットしています。それは問題かもしれないと思いますか? – Adib

+0

あなたのディクテーションに含まれる他のすべてのディクテーションについては、そのディクテーションの内容を構造のルートレベルまで移動したいですか?例えば。 '{'b': 'c'、 'd': 'e'}'は '{'b': 'c'、 'd': 'e'}'になります。 – poke

+0

@あなたは正しいです –

答えて

4

あなたは、ほとんどがあった、あなたがが作成した辞書を返し、再帰呼び出しから返された値で辞書を更新する必要があります。このように使用

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'} 
+0

ああ、ありがとう! –

1

あなたの方法unravelresultsdictの新しいインスタンスあなたは再帰的にそれを呼び出すたびに作成されます。したがって、すべてのデータがマスターディクショナリに入っているわけではありません(つまり、話す)。この代わりのようなものを試してみてください。このような再帰シナリオで

def unravel(data, resultsdict={}): 
    for k in data: 
     if isinstance(data[k],dict): 
      unravel(data[k], resultsdict) 
     else: 
      resultsdict[k] = data[k] 
    return resultsdict 

は、あなたはあなたとあなたが再帰的にすべての時間を変更可能なデータ構造を持っておく必要があります。

+1

実際にここに変更を加えていない場合でも、[変更可能なデフォルトの引数](http://stackoverflow.com/questions/1132941/leastastastish-in-python-the-mutable-default-argument)は避けてください。 – poke

+0

実際、私はその編集を見ませんでした。今それはちょうど壊れている。 'unravel({'a': 'b'})'とそれに続く 'unravel({'b': 'c'})'を試してください。後者は '{'a': 'b'、 'b': 'c'}'を返します。 – poke

+0

私はあなたのソリューションが好きです:D – th3an0maly

0

あなたはすべての辞書のタプルを解凍して全体をフラットにすることができます

# 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]) 
+1

非常に賢いですが、最も読みやすいものではありません! –

+0

は助けになるようにいくつかのコメントを追加しましたが、これはかなり密集したリストの理解だと思います – jfbeltran

+0

私は良い1ライナーを楽しんでいます..私は間違いなくあなたのソリューションを私の銀行に入れます –

関連する問題