私はマルチディクショナリーを持っています:
{'a': {'b': {'c': {'d': '2'}}},
'b': {'b': {'c': {'d': '7'}}},
'c': {'b': {'c': {'d': '3'}}},
'f': {'d': {'c': {'d': '1'}}}}
値に基づいて並べ替えると'2' '3' '7' '1'
、出力は次のようになります。
f.d.c.d.1
a.b.c.d.2
c.b.c.d.3
b.b.c.d.7
私はマルチディクショナリーを持っています:
{'a': {'b': {'c': {'d': '2'}}},
'b': {'b': {'c': {'d': '7'}}},
'c': {'b': {'c': {'d': '3'}}},
'f': {'d': {'c': {'d': '1'}}}}
値に基づいて並べ替えると'2' '3' '7' '1'
、出力は次のようになります。
f.d.c.d.1
a.b.c.d.2
c.b.c.d.3
b.b.c.d.7
固定された形状の構造が得られました。これは、並べ替えが非常に簡単です。
>>> d = {'a': {'b': {'c': {'d': '2'}}}, 'c': {'b': {'c': {'d': '3'}}}, 'b': {'b': {'c': {'d': '7'}}}, 'f': {'d': {'c': {'d': '1'}}}}
>>> sorted(d, key=lambda x: d[x].values()[0].values()[0].values()[0])
['f', 'a', 'c', 'b']
>>> sorted(d.items(), key=lambda x: x[1].values()[0].values()[0].values()[0])
[('f', {'d': {'c': {'d': '1'}}}),
('a', {'b': {'c': {'d': '2'}}}),
('c', {'b': {'c': {'d': '3'}}}),
('b', {'b': {'c': {'d': '7'}}})]
はい、これは少し醜くて不器用ですが、それはあなたの構造が本質的に醜くて不器用だからです。
実際、 の代わりにd['f']
キーがあるという事実を除けば、それはさらに簡単です。タイプミスの可能性があると思いますが、その場合はさらに簡単です。'd'
'b'
>>> d = {'a': {'b': {'c': {'d': '2'}}}, 'c': {'b': {'c': {'d': '3'}}}, 'b': {'b': {'c': {'d': '7'}}}, 'f': {'b': {'c': {'d': '1'}}}}
>>> sorted(d.items(), key=lambda x:x[1]['b']['c']['d'])
[('f', {'b': {'c': {'d': '1'}}}),
('a', {'b': {'c': {'d': '2'}}}),
('c', {'b': {'c': {'d': '3'}}}),
('b', {'b': {'c': {'d': '7'}}})]
他の人が指摘しているように、これは、何をしようとしても、正しいデータ構造ではないことはほぼ確実です。しかし、もしそうなら、これはそれに対処する方法です。
PS、これを「マルチディクショナリ」と呼ぶのは紛らわしいです。defaultdict
その用語は通常、「キーごとに複数の値を持つ可能性のある辞書」を意味します (Python では、おそらくwithlist
またはset
そのデフォルトとして実装する概念)。たまたま辞書が含まれている単一の単一値の辞書は、"ネストされた辞書" と呼ぶ方が適切です。
私の意見では、この種の設計は読みにくく、維持するのが非常に困難です。内部辞書を文字列名に置き換えることを検討できますか?
例えば:
mydict = {
'a.b.c.d' : 2,
'b.b.c.d' : 7,
'c.b.c.d' : 3,
'f.d.c.d' : 1,
}
これは、並べ替えがはるかに簡単で、読みやすいです。
さて、辞書はその性質上、ソートできないものです。したがって、たとえばリスト表現をソートする必要があります。
my_sorted_dict_as_list = sorted(mydict.items(),
key=lambda kv_pair: kv_pair[1])
再帰的に行うことができます:
d = {'a': {'b': {'c': {'d': '2'}}}, 'c': {'b': {'c': {'d': '3'}}}, 'b': {'b': {'c': {'d': '7'}}}, 'f': {'d': {'c': {'d': '1'}}}}
def nested_to_string(item):
if hasattr(item, 'items'):
out = ''
for key in item.keys():
out += '%s.' % key + nested_to_string(item[key])
return out
else:
return item + '\n'
print nested_to_string(d)
また
def nested_to_string(item):
def rec_fun(item, temp, res):
if hasattr(item, 'items'):
for key in item.keys():
temp += '%s.' % key
rec_fun(item[key], temp, res)
temp = ''
else:
res.append(temp + item)
res = []
rec_fun(d, '', res)
return res
なぜこれをしたいのですか。
データ構造は基本的にマルチレベル ツリーなので、必要なことを行う良い方法は、再帰的に実行できる深さ優先トラバーサルと呼ばれるものを実行し、中間結果を少しマッサージして並べ替えることです。それらを目的の形式にフォーマットします。
multidict = {'a': {'b': {'c': {'d': '2'}}},
'b': {'b': {'c': {'d': '7'}}},
'c': {'b': {'c': {'d': '3'}}},
'f': {'d': {'c': {'d': '1'}}}}
def nested_dict_to_string(nested_dict):
chains = []
for key,value in nested_dict.items():
chains.append([key] + visit(value))
chains = ['.'.join(chain) for chain in sorted(chains, key=lambda chain: chain[-1])]
return '\n'.join(chains)
def visit(node):
result = []
try:
for key,value in node.items():
result += [key] + visit(value)
except AttributeError:
result = [node]
return result
print nested_dict_to_string(multidict)
出力:
f.d.c.d.1
a.b.c.d.2
c.b.c.d.3
b.b.c.d.7