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

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

ただいまの
回答率

88.93%

Pythonのdictのvaluesに対するsortについて

解決済

回答 2

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 1,947

mofu_mofu

score 73

みなさん、いつも大変お世話になっております。

yukicoderでPythonを使ってこの問題解いたのですが、解く際にdict型を使ったほうがいいと思ったのでPython sortのまとめ (リスト、辞書型、Series、DataFrame)というqiitaの記事を参考にしましたが、気になる点が2点ありました。

#私の書いたコード(https://yukicoder.me/submissions/240376)

height_dict = {"A":int(input()),"B":int(input()),"C":int(input())}

for k,v in sorted(height_dict.items(), key=lambda x:-x[1]):
    print(k)

①なぜvalue降順ソートはkey=lambda x: -x[1]になるのにkey降順ソートはkey=lambda x: -x[0]になるのか

→dictってindex付けられないんじゃないの?index付けられないのにkeyだと[0]で指定できてvalueだと[1]なの???と思ってしまいます。

例えば、

>>> hoge_dict = {"A":"hoge","B":"fuga","C":"piyo"}
>>> hoge_dict[0]
Traceback (most recent call last):
  File "<input>", line 1, in <module>
KeyError: 0
>>> hoge_dict[-1]
Traceback (most recent call last):
  File "<input>", line 1, in <module>
KeyError: -1


こんな感じに。

(追記)

items()の返り値がtupleになるから???

>>>("A",100)
('A', 100)
>>>("A",100)[0]
'A'
>>>("A",100)[1]
100

key=lambda x: x[1]だと昇順になるがこのx[1]にマイナスをつけると昇順から降順に変わるのはなぜか

→Pythonで他にマイナスを付けたら昇順から降順になるものがなさそうなので違和感がある。hoge.sort(reverse=True)のような引数で降順を指定するイメージしかないため。

実行環境

Python3.6
Mac High Sierra 10.13.3

以上よろしくお願いいたします。

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

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

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

    クリップを取り消します

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

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

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

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

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

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

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

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

    質問の評価を下げる

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

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

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

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

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

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

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

    詳細な説明はこちら

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

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

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

回答 2

checkベストアンサー

+5

以下が正しい(読みやすく理解しやすい)辞書のソートです。

height_dict = dict(a=1, b=-1, c=2, d=-2)

# 基本形: キーの昇順ソート
for k in sorted(height_dict):
    v= height_dict[k]
    print(k, v)
print('*' * 8)

# 基本形の逆順: キーの降順ソート
for k in sorted(height_dict, reverse=True):
    v= height_dict[k]
    print(k, v)
print('*' * 8)

# 基本形の応用: 値の昇順ソート
for k in sorted(height_dict, key=height_dict.get):
    v= height_dict[k]
    print(k, v)
print('*' * 8)

# 基本形の応用の逆順: 値の降順ソート
for k in sorted(height_dict, key=height_dict.get, reverse=True):
    v= height_dict[k]
    print(k, v)
print('*' * 8)

実行結果

a 1
b -1
c 2
d -2
********
d -2
c 2
b -1
a 1
********
d -2
b -1
a 1
c 2
********
c 2
a 1
b -1
d -2
********

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2018/03/02 21:55

    dict.getをキーに渡すのは確かに分かりやすいですね。勉強になります。

    キャンセル

  • 2018/03/02 21:59 編集

    いえいえ、値ソートに関しては辞書が大きくなるとパフォーマンス的に使い物にならない可能性があるので、適材適所かと。

    キャンセル

  • 2018/03/02 23:07

    YouheiSakuraiさん
    sorted()でもreverse=Trueが使えて、かつ、key=height_dict.getで降順が指定できるのですね..!
    とてもわかりやすいanswerをいただいたので、BAとさせていただきます。

    ご丁寧にありがとうございました。

    キャンセル

+3

辞書をソートしているのではなく、dict.items()の結果をソートしているのです。

hoge_dict = {"A": "hoge", "B": "fuga","C": "piyo"}
for kv in hoge_dict.items():
    print(kv, type(kv))

"""実行結果
('A', 'hoge') <class 'tuple'>
('B', 'fuga') <class 'tuple'>
('C', 'piyo') <class 'tuple'>
"""

タプルにキー、バリューの順で格納されているだけです。


②key=lambda x: x[1]だと昇順になるがこのx[1]にマイナスをつけると昇順から降順に変わるのはなぜか

キーの値を元に昇順ソートしているのに変わりはありません。
評価時にマイナスをかけることで、数値の大小関係を逆転させているのです。

hoge.sort(reverse=True)のような引数で降順を指定するイメージしかないため。

引数reverseがあるのならそれを使うのが自然でしょう。

投稿

編集

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2018/03/02 23:03

    LouiS0616さん
    いつも大変お世話になっております。おかげさまで時間をかければ問題を数分〜1時間くらいで解けるようになりました。ありがとうございます。

    ①のitems()の結果はtupleなのですね。なのでdict.items()[0]だとkeyを、dict.items()[1]だとvaluesを返り値するのですね。

    ②に関してですが、dict.values()が例えば[1,2,3,4]なら仮にマイナスを付けたら[-4,-3,-2,-1]になりvaluesが逆になった結果そのkeysが逆になるということでしょうか。

    キャンセル

  • 2018/03/02 23:14

    > ①のitems()の結果はtupleなのですね。なのでdict.items()[0]だとkeyを、dict.items()[1]だとvaluesを返り値するのですね。

    ちょっと違います。
    dict.items()の返り値はタプルではなく、タプルを毎周返すイテラブルなオブジェクトです。
    dict.items()[0]とアクセスすることは出来ません。

    ---
    > ②に関してですが、dict.values()が例えば[1,2,3,4]なら仮にマイナスを付けたら[-4,-3,-2,-1]になりvaluesが逆になった結果そのkeysが逆になるということでしょうか。

    分かりづらい言い方になってしまいました。
    この文脈では、キーは『辞書のキー』ではなく『ソートのキー』です。
    ややこしいですが、『ソートのキーに辞書のバリューの反数を指定』しているのです。

    平たく言えば、例えば`my_dict = {'a': 1, 'b': 2, 'c': 3}`に対して、
    ソート時だけ`my_dict = {'a': -1, 'b': -2, 'c': -3}`と見なしている感じです。

    キャンセル

  • 2018/03/02 23:22

    リストを色んな指標でソートして練習してみると良いかもしれません。
    例えば`my_list = [-2, -1, 0, 1, 2]`を絶対値の昇順に並び替える、とか。

    キャンセル

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

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

関連した質問

同じタグがついた質問を見る