質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

90.22%

pythonの辞書型について

解決済

回答 3

投稿

  • 評価
  • クリップ 1
  • VIEW 1,072

waya

score 18

pythonの辞書型をソートした際に,スマートに新しく定義できる方法はないでしょうか?
例えば今までソートしたものを以下のように新しい辞書型に移し変えていました.

new_dic = {}
for key,item in sorted(original_dic.items()):
    new_dic[key] = item

元の辞書型をsorted関数に引数として入れるだけでは返り値にソートした値を返すだけだと思うのですが,他にもっとスマートな方法はあるでしょうか?
仮にソートしたものを以下のように新しい変数に定義するとエラーが出てしまいます.

new_dic = sorted(original_dic.items())

エラーは以下のように出てきます

AttributeError: 'list' object has no attribute 'values'

ご回答よろしくお願いします.

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • Lhankor_Mhy

    2017/05/25 12:32

    Pythonの辞書は順序を保存しないと記憶しています。

    キャンセル

回答 3

checkベストアンサー

+2

すでに回答あるとおり、dictは格納されたkey,valueの順序を保証しませんし、ソートした結果を新しい辞書に格納しても同じことです。

順序を保持したい場合は順序付き辞書 (ordered dictionary) を利用します。

from collections import OrderedDict
original_dic = {3:"three",2:"two",1:"one"}

# t[0]=key順にsortしてその順に追加(構築)。OrderedDictは追加順を保持する。
new_dic = OrderedDict(sorted(original_dic.items(), key=lambda t: t[0]))
print(type(new_dic)) # <class 'collections.OrderedDict'>

for key,item in new_dic.items():
    print(key,item)

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/05/25 17:26

    勉強になります。
    自分には少し難しいですが
    要は環境変数依存?で順序付辞書を使うのが安定という事でいいんですかね
    お二人方付き合ってくださってありがとうございます><

    キャンセル

  • 2017/05/25 17:32

    私も流し読みでの把握にとどまってますがw、ようは実行環境(CPython)依存ですね。
    なのでそれ以外の実行環境も考慮するならOrderedDictを利用すべきだと思います。

    キャンセル

  • 2017/05/29 11:54

    ご丁寧にありがとうございました.
    みなさんのコメントが非常に参考になりました.

    キャンセル

0

そもそも
Pythonの辞書(dict)では、keyを登録した順番は記憶されませんということで、ご提示のプログラムでは、new_dicは御期待の内容では無いのでは?と思うのですが・・・・

それは置いておくとすると、

new_dic=dict(sorted(original_dic.items()))


とすれば、御提示のプログラムと同様の動作になるかと思います。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/05/25 16:08

    なるほど,辞書型で順番が記憶されないということを完全に忘れておりました...。
    勉強不足でお恥ずかしいです。
    ありがとうございます.無事できました.

    キャンセル

  • 2017/05/29 10:30

    私も知らなかったのですが、Python3.6?では実装依存で保存されるようですね。

    そうであっても、仕様を理解してその範囲内でプログラムを書くくせをつけておくことは大切なことかと思います。

    キャンセル

  • 2017/05/29 11:53

    ご回答ありがとうございます.
    少し気持ちを引き締めてこれがら頑張ります.

    キャンセル

0

※これは回答ではありません
コメントに書くとインデントがずれる為こちらに書かせて頂きます

自分の環境だといつからか辞書が順序を保障してくれるようになっていて(恐らくpython3.6環境から?)、順序を記憶しないのは昔の事だと思って居のですが違うのでしょうか

b = {}

b["勇者"] = {"HP":100, "攻撃力":50, "防御":30, "素早さ":20, "賢さ":15}
b["賢者"] = {"HP":70 , "攻撃力":30, "防御":20, "素早さ":15, "賢さ":55}
b["剣士"] = {"HP":110, "攻撃力":75, "防御":40, "素早さ":25, "賢さ":5}

for key,value in b.items():
    print(key)
    for i in list(value.keys()):
        print(i)
b = {
"勇者":{"HP":100, "攻撃力":50, "防御":30, "素早さ":20, "賢さ":15},
"賢者":{"HP":70 , "攻撃力":30, "防御":20, "素早さ":15, "賢さ":55},
"剣士":{"HP":110, "攻撃力":75, "防御":40, "素早さ":25, "賢さ":5},
}

for key,value in b.items():
    print(key)
    for i in list(value.keys()):
        print(i)

例えばこれらのコードでしたら私の環境だと、必ず同じ順序(追加した順序)で表示されます。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/05/25 17:08

    コメントありがとうございます。
    あちらでLhankor_Mhyさんに情報提供いただきました。過去に同様の質問あり(https://teratail.com/questions/69286)実装依存のようです。

    キャンセル

  • 2017/05/25 17:27

    ご丁寧にありがとうございます><

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 90.22%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる