辞書の操作

Sorting multiple dictionary dimensions at once [Python] – StackOverflow

この手の操作ではdefaultdictを使うのがリーズナブルチョイス.

from collections import defaultdict
from collections import OrderedDict


d = {
    "b":{
          "ba": {
                 "Score":3,
                 "N":500
                },
          "aa": {
                 "Score": 10,
                 "N":300
                },
        },
    "a":{
         "xy": {
                 "Score":199,
                 "N":7
               },
         "zz": {
                 "Score":222,
                 "N":55
               },
         }
}

dd = defaultdict(OrderedDict)
for k, v in d.items():
    for vk, ve in sorted(v.items(), key=lambda x: x[1]['Score'], reverse=True):
        dd[k][vk] = ve
dd

defaultdict(collections.OrderedDict,
{‘a’: OrderedDict([(‘zz’, {‘N’: 55, ‘Score’: 222}),
(‘xy’, {‘N’: 7, ‘Score’: 199})]),
‘b’: OrderedDict([(‘aa’, {‘N’: 300, ‘Score’: 10}),
(‘ba’, {‘N’: 500, ‘Score’: 3})])})

OrderedDict([(k, OrderedDict(sorted(v.items(), key=lambda x: x[1]['Score'], reverse=True))) for k, v in sorted(d.items())])

OrderedDict([(‘a’,
OrderedDict([(‘zz’, {‘N’: 55, ‘Score’: 222}),
(‘xy’, {‘N’: 7, ‘Score’: 199})])),
(‘b’,
OrderedDict([(‘aa’, {‘N’: 300, ‘Score’: 10}),
(‘ba’, {‘N’: 500, ‘Score’: 3})]))])

%%timeit
dd = defaultdict(OrderedDict)
for k, v in d.items():
    for vk, ve in sorted(v.items(), key=lambda x: x[1]['Score'], reverse=True):
        dd[k][vk] = ve
dd

9.45 µs ± 234 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)

%%timeit
OrderedDict([(k, OrderedDict(sorted(v.items(), key=lambda x: x[1]['Score'], reverse=True))) for k, v in sorted(d.items())])

14.9 µs ± 146 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)

Python 3.6.x系では追加された順序が維持されるので,OrderedDictを使わなくても以下の様にできる.
……と思ったんだけど,

dd = {}
for k, v in sorted(d.items()):
    for vk, ve in sorted(v.items(), key=lambda x: x[1]['Score'], reverse=True):
        dd.setdefault(k, {}).setdefault(vk, ve)
dd

{‘a’: {‘xy’: {‘N’: 7, ‘Score’: 199}, ‘zz’: {‘N’: 55, ‘Score’: 222}},
‘b’: {‘aa’: {‘N’: 300, ‘Score’: 10}, ‘ba’: {‘N’: 500, ‘Score’: 3}}}

dd = {k: {vk: ve for vk, ve in sorted(v.items(), key=lambda x: x[1]['Score'], reverse=True)} for k, v in sorted(d.items())}
dd

{‘a’: {‘xy’: {‘N’: 7, ‘Score’: 199}, ‘zz’: {‘N’: 55, ‘Score’: 222}},
‘b’: {‘aa’: {‘N’: 300, ‘Score’: 10}, ‘ba’: {‘N’: 500, ‘Score’: 3}}}

辞書内辞書の挿入順序は維持されないんだろうか.

広告
カテゴリー: 未分類 パーマリンク

辞書の操作 への2件のフィードバック

  1. ピンバック: how to compare values inside list in python? | 粉末@それは風のように (日記)

  2. ピンバック: 2つのリストから辞書を作る | 粉末@それは風のように (日記)

コメントを残す

以下に詳細を記入するか、アイコンをクリックしてログインしてください。

WordPress.com ロゴ

WordPress.com アカウントを使ってコメントしています。 ログアウト / 変更 )

Twitter 画像

Twitter アカウントを使ってコメントしています。 ログアウト / 変更 )

Facebook の写真

Facebook アカウントを使ってコメントしています。 ログアウト / 変更 )

Google+ フォト

Google+ アカウントを使ってコメントしています。 ログアウト / 変更 )

%s と連携中