辞書を値でソートするにはどうすればよいですか?


3422

データベースの2つのフィールド(文字列フィールドと数値フィールド)から読み取った値の辞書があります。文字列フィールドは一意であるため、それが辞書のキーになります。

キーでソートできますが、値に基づいてソートするにはどうすればよいですか?

注:私はここでスタックオーバーフローの質問を読みました。辞書のリストを辞書の値で並べ替えるにはどうすればよいですか。おそらく、コードを変更して辞書のリストを作成することもできますが、辞書のリストは実際には必要ないので、昇順または降順で並べ替える簡単な解決策があるかどうかを知りたいと思いました。


9
辞書のデータ構造には固有の順序はありません。反復することはできますが、反復が特定の順序に従うことを保証するものはありません。これは設計によるものであるため、最善の策はおそらく表現にanohterデータ構造を使用することです。
Daishiman 2010

135
"sorted()"は辞書を操作できる(そしてソートされたキーのリストを返す)ので、彼はこれを知っていると思う。彼のプログラムを知らなければ、間違ったデータ構造を使用していると誰かに言うのはばかげたことです。90%の時間で高速検索が必要な場合、おそらく辞書が必要です。
bobpaul 2013

すべての辞書をソートするための3つの出力(キー、値、その両方)が明確で簡潔なスタイルで、ここで覆われている:stackoverflow.com/questions/16772071/sort-dict-by-value-python
JStrahl

2
@Daishiman基本クラスは注文されない場合がありますが、OrderedDictはもちろんです。
テイラーエドミストン2017

1
Python 3.6以降では、辞書は挿入順序を保持します。もちろん、これは値でソートする可能性と同じではありませんが、「辞書データ構造には固有の順序がない」と言ってももはや有効ではありません。
Konrad Kocik

回答:


4953

Python 3.6以降

x = {1: 2, 3: 4, 4: 3, 2: 1, 0: 0}
{k: v for k, v in sorted(x.items(), key=lambda item: item[1])}
{0: 0, 2: 1, 1: 2, 4: 3, 3: 4}

古いPython

辞書をソートすることはできません。ソートされた辞書の表現を取得するためだけです。辞書は本質的に順序がありませんが、リストやタプルなどの他のタイプはそうではありません。したがって、並べ替えられた値を表すために順序付けられたデータ型が必要です。これはリスト、おそらくタプルのリストになります。

例えば、

import operator
x = {1: 2, 3: 4, 4: 3, 2: 1, 0: 0}
sorted_x = sorted(x.items(), key=operator.itemgetter(1))

sorted_x各タプルの2番目の要素でソートされたタプルのリストになります。dict(sorted_x) == x

そして、値の代わりにキーでソートしたい人のために:

import operator
x = {1: 2, 3: 4, 4: 3, 2: 1, 0: 0}
sorted_x = sorted(x.items(), key=operator.itemgetter(0))

Python3では解凍が許可されていないため[1]使用できます

x = {1: 2, 3: 4, 4: 3, 2: 1, 0: 0}
sorted_x = sorted(x.items(), key=lambda kv: kv[1])

出力を辞書として使いたい場合は、以下を使用できますcollections.OrderedDict

import collections

sorted_dict = collections.OrderedDict(sorted_x)

43
:値スキームによってソート様々な辞書のタイミングについて writeonly.wordpress.com/2008/08/30/...
グレッグリンド

164
sorted_x.reverse()降順(2番目のtuple要素による)になります
Saidimu apale

414
saidimu:は既にを使用しているのでsorted()reverse=True引数を渡す方がはるかに効率的です。
rmh 2010

121
python3では、ラムダを使用しましたsorted(d.items(), key=lambda x: x[1])。これはpython 2.xで動作しますか?
KEYO

84
OrderedDictが2.7のコレクションに追加されました。:で示されている例をソートdocs.python.org/library/...
monkut

1264

単純な: sorted(dict1, key=dict1.get)

まあ、実際には「ディクショナリ値によるソート」が可能です。最近、私はコードゴルフでそれをしなければなりませんでした(スタックオーバーフローの質問コードゴルフ:ワード頻度チャート)。要約すると、問題はその種のものでした。テキストを指定して、各単語が出現する頻度をカウントし、頻度の高い順にソートされた上位の単語のリストを表示します。

単語をキーとして、各単語の出現回数を値として辞書を作成する場合、ここでは次のように簡略化します。

from collections import defaultdict
d = defaultdict(int)
for w in text.split():
    d[w] += 1

次に、使用頻度でsorted(d, key=d.get)並べ替えられた単語のリストを取得できます-ソートは、出現する単語の数をソートキーとして使用して、辞書キーを反復処理します。

for w in sorted(d, key=d.get, reverse=True):
    print(w, d[w])

私はこの詳細な説明を書いて、「辞書をキーで簡単に並べ替えることができるが、値で並べ替える方法」という意味をよく示しています。元の投稿はそのような問題に対処しようとしていたと思います。そして解決策は、上記のように、値に基づいてキーのリストを並べ替えることです。


31
これも良いことですがkey=operator.itemgetter(1)、効率よりもスケーラブルでなければなりませんkey=d.get
smci

3
@raylu私はitemgetterを使用して「動作しない」動作を観察します:----- ------ from operator import itemgetter d = {"a":7, "b":1, "c":5, "d":3} sorted_keys = sorted(d, key=itemgetter, reverse=True) for key in sorted_keys: print "%s: %d" % (key, d[key]) > b:1 c:5 a:7 d:3コードを実行するたびに結果が変化します:奇妙。(申し訳ありませんが、コードを正しく表示できません)
bli

12
@bli sorted_keys = sorted(d.items(), key=itemgetter(1), reverse=True)およびfor key, val in sorted_keys: print "%s: %d" % (key, val)-itemgetterは、呼び出されたときに関数を作成します。例のように直接使用することはありません。そして、dictでの単純な反復は、値のないキーを使用します
Izkata

18
私は未来からあなたに言うために来ましたcollections.Counter、それはあなたにmost_common興味があるかもしれない方法があります:)
Eevee

2
@Eevee-f2f以外の短いコメントで誤解されるリスクがあります。Amuzing tidbit:collections.Counterは2.7で追加され、ほぼ7年前にリリースされました!(私はそれについては知りませんでした-それに加えて、簡潔にするためにコードゴルフでそれを避けたでしょう、それはゲームの唯一の執着です)
Nas Banov

859

あなたは使うことができます:

sorted(d.items(), key=lambda x: x[1])

これにより、ディクショナリ内の各エントリの値によってディクショナリが最小から最大にソートされます。

降順に並べ替えるには、次を追加しreverse=Trueます。

sorted(d.items(), key=lambda x: x[1], reverse=True)

入力:

d = {'one':1,'three':3,'five':5,'two':2,'four':4}
a = sorted(d.items(), key=lambda x: x[1])    
print(a)

出力:

[('one', 1), ('two', 2), ('three', 3), ('four', 4), ('five', 5)]

私が見たもの(docs.python.org/2/library/…)から、OrderedDictと呼ばれるクラスがあります。これは、辞書でありながらソートされ、順序を保持できます。コード例から、ラムダを使用して並べ替えることができますが、私は個人的には試していません:P
UsAndRufus

53
私はkey=lambda (k, v): v個人的に好みます
Claudiu

35
@Claudiuその(k, v)構文も好きですが、タプルパラメータのアンパッキングが削除されたPython 3では使用できません。
Bob Stein、

2
dict(sorted(d.items(), key=lambda x: x[1]))
Dr_Hope

3
第タプルのソートされたリストから辞書を作成すると、再び順位を殺す...
ジャン=フランソワ・ファーブル

233

辞書はソートできませんが、それらからソートされたリストを作成できます。

ソートされたdict値のリスト:

sorted(d.values())

値でソートされた(キー、値)ペアのリスト:

from operator import itemgetter
sorted(d.items(), key=itemgetter(1))

同じ値のキーはどの順序で配置されますか?最初にキーで、次に値でリストをソートしましたが、同じ値を持つキーの順序が残っていません。
SabreWolfy

1
CPython 3.6以降、および3.7以降のその他すべてのPython実装で、辞書をソートできるようになりました
Boris

161

最近のPython 2.7では、アイテムが追加された順序を記憶する新しいOrderedDict型があります。

>>> d = {"third": 3, "first": 1, "fourth": 4, "second": 2}

>>> for k, v in d.items():
...     print "%s: %s" % (k, v)
...
second: 2
fourth: 4
third: 3
first: 1

>>> d
{'second': 2, 'fourth': 4, 'third': 3, 'first': 1}

元の辞書から順序付けされた新しい辞書を作成するには、値で並べ替えます。

>>> from collections import OrderedDict
>>> d_sorted_by_value = OrderedDict(sorted(d.items(), key=lambda x: x[1]))

OrderedDictは通常の辞書のように動作します。

>>> for k, v in d_sorted_by_value.items():
...     print "%s: %s" % (k, v)
...
first: 1
second: 2
third: 3
fourth: 4

>>> d_sorted_by_value
OrderedDict([('first': 1), ('second': 2), ('third': 3), ('fourth': 4)])

5
これは、問題が何であるかではない-それはキーの順序を維持するが、約「の値によってソート」に関するものではありません
ナズBanov

10
@Nas Banov:キーによるソートではありません。並べ替え順で、アイテムを作成します。この例では、値で並べ替えます。残念ながら、3項目のdictが選択されたため、値とキーで並べ替えたときの順序は同じだったため、サンプルのdictを拡張しました。
mykhal

sorted(d.items(), key=lambda x: x[1])どういうx意味か、なぜそれがx[1]ラムダになるのかを説明できますか?なぜそれができないのx[0]ですか?どうもありがとうございました!
JZAU 2013年

1
@Boern d.items()(key, value)タプルのリストのようなコンテナを返します。[0]タプルの最初の要素(キー)に[1]アクセスし、2番目の要素(値)にアクセスします。
BallpointBen

2
注:(CPythonと/ PyPyの実装の詳細など)3.6のようおよび(Python言語の保証として)3.7のように、平野はdictあなただけで交換できるように挿入は、同様に命じているOrderedDictdictコードのために、現代のPython上で実行されています。OrderedDict既存のdictmove_to_end/を使用したpopitem)順序を再配置する必要がある場合、または等値比較で順序を区別する必要がある場合を除き、これは実際には必要ありません。それはプレーンよりもはるかに多くのメモリを使用するdictので、可能であればそれを行うdict方法です。
ShadowRanger、

104

更新:Python 3.5を使用した2015年12月5日

受け入れられた回答が役に立ったと思いながら、このタイプの問題を正確に解決するために設計された、実行可能な最新の代替手段として、標準ライブラリコレクションモジュールのOrderedDictを参照するように更新されていないことにも驚きました。

from operator import itemgetter
from collections import OrderedDict

x = {1: 2, 3: 4, 4: 3, 2: 1, 0: 0}
sorted_x = OrderedDict(sorted(x.items(), key=itemgetter(1)))
# OrderedDict([(0, 0), (2, 1), (1, 2), (4, 3), (3, 4)])

公式のOrderedDictドキュメントも非常によく似た例を提供していますが、並べ替え関数にラムダを使用しています。

# regular unsorted dictionary
d = {'banana': 3, 'apple':4, 'pear': 1, 'orange': 2}

# dictionary sorted by value
OrderedDict(sorted(d.items(), key=lambda t: t[1]))
# OrderedDict([('pear', 1), ('orange', 2), ('banana', 3), ('apple', 4)])

86

ハンクゲイの答えとほとんど同じです:

sorted([(value,key) for (key,value) in mydict.items()])

または、John Fouhyによって提案されたようにわずかに最適化:

sorted((value,key) for (key,value) in mydict.items())

9
..そしてハンクゲイの答えと同様に、角括弧は必要ありません。sorted()は、ジェネレーター式などのイテラブルを喜んで受け取ります。
John Fouhy

(value、key)タプル要素を入れ替えて(key、value)にする必要があるかもしれません。次に、別のリストの理解が必要です。 [(key, value) for (value, key) in sorted_list_of_tuples]
Saidimu apale

いいえ、sortedとにかくリストを再構築する必要があり、gencompからの再構築の方が高速になるため、角括弧はそのままにしておくことをお勧めします。コードゴルフには適していますが、速度は良くありません。醜い([])バージョンを維持します。
ジャン=フランソワ・ファーブル

75

namedtupleを使用すると非常に便利です。たとえば、キーとして「名前」、値として「スコア」のディクショナリがあり、「スコア」でソートしたいとします。

import collections
Player = collections.namedtuple('Player', 'score name')
d = {'John':5, 'Alex':10, 'Richard': 7}

最初にスコアが低い順に並べ替えます。

worst = sorted(Player(v,k) for (k,v) in d.items())

最初に最高スコアのソート:

best = sorted([Player(v,k) for (k,v) in d.items()], reverse=True)

名前とスコアを取得できるようになりました。次のように、Pythonで2番目に優れたプレーヤー(index = 1)を非常にPythonで表現するとします。

player = best[1]
player.name
    'Richard'
player.score
    7

辞書に戻すにはどうすればよいですか?
ロウナナ2017

as_list = [Player(v、k)for(k、v)in d.items()] as_dict = dict((p.name、p.score)for p in as_list)
Remi

72

以下のようPythonの3.6内蔵の辞書を注文することになります

朗報です。OPがデータベースから取得したペアを一意の文字列IDをキーとして、数値を値として組み込みのPython v3.6 +辞書にマッピングするという元の使用例では、挿入順序を尊重する必要があります。

次のようなデータベースクエリから結果として得られる2つの列テーブル式を言う場合:

SELECT a_key, a_value FROM a_table ORDER BY a_value;

2つのPythonタプルk_seqとv_seqに格納されます(数値インデックスによって整列され、コースの長さは同じです)。

k_seq = ('foo', 'bar', 'baz')
v_seq = (0, 1, 42)
ordered_map = dict(zip(k_seq, v_seq))

後で出力できるようにします:

for k, v in ordered_map.items():
    print(k, v)

この場合、yield(新しいPython 3.6+組み込みdictの場合!):

foo 0
bar 1
baz 42

vの値ごとに同じ順序で。

私のマシンにPython 3.5をインストールすると、次のようになります。

bar 1
foo 0
baz 42

詳細:

レイモンドヘッティンガーによって2012年に提案されたように(件名"高速な反復によるよりコンパクトな辞書"の python-devのメールを参照)、現在(2016年に)件名"Python 3.6 dictを持つpython-devへのVictor Stinnerのメールで発表されました"課題27350 「コンパクトで順序付けられた辞書」の修正/実装により、コンパクトになり、プライベートバージョンが取得され、キーワードが順序付けされます。を使用して挿入順序を維持できるようになります。

うまくいけば、これが最初のステップとして薄層OrderedDict実装につながるでしょう。@ JimFasarakis-Hilliardが示したように、一部ではOrderedDictタイプのユースケースも将来的に見られます。これが時の試練に耐えられるかどうか、そして次のステップがどうなるかについて、Pythonコミュニティ全体が注意深く調査すると思います。

以下の安定した順序付けによって開かれる可能性を見逃さないように、コーディングの習慣を再考する時間です。

  • キーワード引数と
  • (中間)dictストレージ

1つ目は、場合によっては関数やメソッドの実装でディスパッチが容易になるためです。

2つ目は、dictパイプラインの処理で中間ストレージとしてs をより簡単に使用することを奨励しています。

レイモンドヘッティンガーは、サンフランシスコのPythonミートアップグループプレゼンテーション2016-DEC-08から「The Tech Behind Python 3.6 Dictionaries」を説明するドキュメントを提供してくれました。

そして、おそらくかなりの数のStack Overflowの高品質の質問と回答のページがこの情報のバリエーションを受け取り、多くの高品質の回答もバージョンごとの更新を必要とします。

警告エンプター(ただし、下記の更新2017-12-15も参照):

@ajcrが正しく指摘しているように、「この新しい実装の順序を維持する側面は、実装の詳細と見なされており、信頼すべきではありません。」(whatsnew36から)摘み取りではありません、引用は少し悲観的になりました;-)。「これは今後も続く可能性があります(ただし、将来的には変更される可能性がありますが、現在および将来のすべてのPython実装の順序を保持するセマンティクスを言語仕様に変更する前に、いくつかのリリースでこの新しいdict実装を言語で実装することが望まれます。これもまたランダムな反復順序がまだ有効である古いバージョンの言語(Python 3.5など)との下位互換性を維持するのに役立ちます。」

そのため、一部の人間の言語(ドイツ語など)と同様に、使用法によって言語が形成され、willが宣言されました... whatsnew36で

2017-12-15の更新:

python-devのリストへのメール、グイド・ヴァンロッサムは宣言しました:

そうする。「口述は挿入順序を保つ」が判決です。ありがとう!

そのため、dict挿入順序付けのバージョン3.6 CPython副作用は、言語仕様の一部になりました(実装の詳細だけではなくなりました)。そのメールスレッドはcollections.OrderedDict、ディスカッション中にレイモンドヘッティンガーによって思い出されたように、いくつかの際立った設計目標も浮上しました。


15
リンク先の「whatsnew」ページの警告を強調する必要があります。この新しい実装の順序を維持する側面は、実装の詳細と見なされるため、信頼すべきではありませんdict型がコード内の挿入順序を尊重すると誰も想定してはなりません。これは言語の定義の一部ではなく、実装は将来のリリースで変更される可能性があります。引き続き使用OrderedDictして注文を保証します。
Alex Riley

@ajcr警告に感謝します、非常に感謝します-スマイリーや多分私の応答に織り込まれたように、これらは示されるべきです、変更は大規模ですが、もちろんCPython(参照実装)とPyPyでのみ利用可能です。まったく異なるものについて...マンマシン命令をコーディングするときに、実装以外の詳細について話すことはめったにありません。それがJythonだけだったら;-) ...私はそれを書く勇気を持っていなかったかもしれません。
Dilettant

OrderedDict絶対に落とされることはありません。代わりに、現在のdict実装の薄いラッパーになります(そのため、よりコンパクトになることも追加できます)。そのスニペットをに追加することは、役に立たImportErrorない読者を誤解させるため、あまり良いアイデアとは言えませんOrderedDict
Dimitris Fasarakis Hilliard

@ JimFasarakis-Hilliardフィードバックありがとうございます。「かなり良いアイデア」で笑顔になりました。将来を予測するのは難しい場合がよくあります。しかし、私はあなたの提案がソースをチェックし、それを試し、それに応じて答えを更新するのが好きです。再度、感謝します。
Dilettant

8
@AlexRileyこの警告は正確ではなくなりました。Python3.7は順序付けされた辞書を保証します。
gerrit

42

私は同じ問題を抱えていました、そして私はこのようにそれを解決しました:

WantedOutput = sorted(MyDict, key=lambda x : MyDict[x]) 

(「dictをソートすることはできません」と答えた人は質問を読みませんでした!実際、「キーでソートできますが、値に基づいてソートするにはどうすればよいですか?」値の値に従ってソートされたキー。)

順序が適切に定義されていないことに注意してください(同じ値のキーは、出力リストでは任意の順序になります)。


1
結果に値がありません
Dejell

ディクショナリを反復することと、キーで値をフェッチすることの両方に注意してください。したがって、パフォーマンスの点でこれは最適なソリューションではありません。
Ron Klein

1
@Dejell:寄稿者が言うように、彼は質問を「値に従ってソートされたキーのリストを取得できますか」と解釈します。結果の値は必要ありません。辞書にあります。
最大

36

値が数値の場合はCounterコレクションからも使用できます。

from collections import Counter

x = {'hello': 1, 'python': 5, 'world': 3}
c = Counter(x)
print(c.most_common())

>> [('python', 5), ('world', 3), ('hello', 1)]    

辞書が>>> x = {'hello':1、 'python':5、 'world':300}の場合は
どうでしょう

@yopy Counter({'hello':1, 'python':5, 'world':300}).most_common()は与える[('world', 300), ('python', 5), ('hello', 1)]。これは実際には、並べ替え可能なすべての値の種類で機能します(他の多く Counter操作では、intに相当する値が必要です)。
lvc 2013

34

Python 2.7では、次のようにします。

from collections import OrderedDict
# regular unsorted dictionary
d = {'banana': 3, 'apple':4, 'pear': 1, 'orange': 2}

# dictionary sorted by key
OrderedDict(sorted(d.items(), key=lambda t: t[0]))
OrderedDict([('apple', 4), ('banana', 3), ('orange', 2), ('pear', 1)])

# dictionary sorted by value
OrderedDict(sorted(d.items(), key=lambda t: t[1]))
OrderedDict([('pear', 1), ('orange', 2), ('banana', 3), ('apple', 4)])

コピーして貼り付け:http : //docs.python.org/dev/library/collections.html#ordereddict-examples-and-recipes

楽しい ;-)


25

これはコードです:

import operator
origin_list = [
    {"name": "foo", "rank": 0, "rofl": 20000},
    {"name": "Silly", "rank": 15, "rofl": 1000},
    {"name": "Baa", "rank": 300, "rofl": 20},
    {"name": "Zoo", "rank": 10, "rofl": 200},
    {"name": "Penguin", "rank": -1, "rofl": 10000}
]
print ">> Original >>"
for foo in origin_list:
    print foo

print "\n>> Rofl sort >>"
for foo in sorted(origin_list, key=operator.itemgetter("rofl")):
    print foo

print "\n>> Rank sort >>"
for foo in sorted(origin_list, key=operator.itemgetter("rank")):
    print foo

結果は次のとおりです。

元の

{'name': 'foo', 'rank': 0, 'rofl': 20000}
{'name': 'Silly', 'rank': 15, 'rofl': 1000}
{'name': 'Baa', 'rank': 300, 'rofl': 20}
{'name': 'Zoo', 'rank': 10, 'rofl': 200}
{'name': 'Penguin', 'rank': -1, 'rofl': 10000}

Rofl

{'name': 'Baa', 'rank': 300, 'rofl': 20}
{'name': 'Zoo', 'rank': 10, 'rofl': 200}
{'name': 'Silly', 'rank': 15, 'rofl': 1000}
{'name': 'Penguin', 'rank': -1, 'rofl': 10000}
{'name': 'foo', 'rank': 0, 'rofl': 20000}

ランク

{'name': 'Penguin', 'rank': -1, 'rofl': 10000}
{'name': 'foo', 'rank': 0, 'rofl': 20000}
{'name': 'Zoo', 'rank': 10, 'rofl': 200}
{'name': 'Silly', 'rank': 15, 'rofl': 1000}
{'name': 'Baa', 'rank': 300, 'rofl': 20}

25

次の方法を試してください。次のデータでmydictという辞書を定義してみましょう。

mydict = {'carl':40,
          'alan':2,
          'bob':1,
          'danny':3}

辞書をキーでソートしたい場合、次のようなことができます:

for key in sorted(mydict.iterkeys()):
    print "%s: %s" % (key, mydict[key])

これにより、次の出力が返されます。

alan: 2
bob: 1
carl: 40
danny: 3

一方、(質問で尋ねられるように)値で辞書をソートしたい場合、次のようにすることができます:

for key, value in sorted(mydict.iteritems(), key=lambda (k,v): (v,k)):
    print "%s: %s" % (key, value)

このコマンドの結果(ディクショナリを値でソート)は、次を返します。

bob: 1
alan: 2
danny: 3
carl: 40

驚くばかり!for key, value in sorted(mydict.iteritems(), key=lambda (k,v): v["score"]):サブキーで並べ替えることができます
Andomar 2017

Python3のラムダに近い構文エラーが発生します
Suleman Elahi

21

Python 3.6以降、dictオブジェクトは挿入順に並べ替えられます。Python 3.7の仕様に正式に準拠しています。

>>> words = {"python": 2, "blah": 4, "alice": 3}
>>> dict(sorted(words.items(), key=lambda x: x[1]))
{'python': 2, 'alice': 3, 'blah': 4}

それ以前は、を使用する必要がありましたOrderedDict

Python 3.7ドキュメントは言う:

バージョン3.7で変更:辞書順は挿入順であることが保証されています。この動作は、3.6からのCPythonの実装の詳細でした。


よく働く!dict(sorted(words.items(), key=lambda x: x[1], reverse=True))DESC向け
vizyourdata 2018年

20

「逆索引」を作成することもできます

from collections import defaultdict
inverse= defaultdict( list )
for k, v in originalDict.items():
    inverse[v].append( k )

これで、逆に値が設定されました。各値には、適用可能なキーのリストがあります。

for k in sorted(inverse):
    print k, inverse[k]

19

collections.Counterを使用できます。これは、数値と非数値の両方で機能することに注意してください。

>>> x = {1: 2, 3: 4, 4:3, 2:1, 0:0}
>>> from collections import Counter
>>> #To sort in reverse order
>>> Counter(x).most_common()
[(3, 4), (4, 3), (1, 2), (2, 1), (0, 0)]
>>> #To sort in ascending order
>>> Counter(x).most_common()[::-1]
[(0, 0), (2, 1), (1, 2), (4, 3), (3, 4)]
>>> #To get a dictionary sorted by values
>>> from collections import OrderedDict
>>> OrderedDict(Counter(x).most_common()[::-1])
OrderedDict([(0, 0), (2, 1), (1, 2), (4, 3), (3, 4)])

7
これはIvan Sasの回答とどう違うのですか?
Peter Mortensen 2014

15

値で永続的にソートされる辞書であるスキップディクテーションを使用できます。

>>> data = {1: 2, 3: 4, 4: 3, 2: 1, 0: 0}
>>> SkipDict(data)
{0: 0.0, 2: 1.0, 1: 2.0, 4: 3.0, 3: 4.0}

を使用する場合keys()values()またはitems()値でソートした順序で反復します。

スキップリストのデータ構造を使用して実装されています。


並べ替えの順序を変更できますか?現在、昇順ですが、降順にしたいです。
Suleman Elahi

あなたは順序を逆にするために、自分の価値観を否定しなければならない私の知る限り
malthe

うわー、私はそのように考える...ありがとう。
スレマンエラヒ

14

キーに渡すことができるカスタム関数を使用することもできます。

def dict_val(x):
    return x[1]
x = {1: 2, 3: 4, 4: 3, 2: 1, 0: 0}
sorted_x = sorted(x.items(), key=dict_val)

12
from django.utils.datastructures import SortedDict

def sortedDictByKey(self,data):
    """Sorted dictionary order by key"""
    sortedDict = SortedDict()
    if data:
        if isinstance(data, dict):
            sortedKey = sorted(data.keys())
            for k in sortedKey:
                sortedDict[k] = data[k]
    return sortedDict

2
問題は、キーではなく値でソートすることでした...関数を見るのが好きです。コレクションをインポートして、もちろんsorted(data.values())を使用することができます
Remi

10

Dilettantによって指摘されたように、Python 3.6は今や順序を維持します!イテラブル(タプル、リスト、dict)の並べ替えを容易にする、私が書いた関数を共有したいと思いました。後者の場合、キーまたは値のいずれかでソートでき、数値比較を考慮に入れることができます。3.6以上の場合のみ!

たとえば文字列やintを保持するイテラブルでソートを使用しようとすると、sorted()は失敗します。もちろんstr()で文字列比較を強制できます。ただし、がより小さい実際の数値比較を実行したい場合があります(これは文字列比較ではそうではありません)。だから私は次のことを思いつきました。明示的な数値比較が必要な場合は、フラグを使用して、すべての値を浮動小数点数に変換しようとすることにより、明示的な数値ソートを試みます。それが成功した場合は、数値の並べ替えを行います。それ以外の場合は、文字列の比較に頼ります。1220num_as_num

改善やプッシュリクエストへのコメントを歓迎します。

def sort_iterable(iterable, sort_on=None, reverse=False, num_as_num=False):
    def _sort(i):
      # sort by 0 = keys, 1 values, None for lists and tuples
      try:
        if num_as_num:
          if i is None:
            _sorted = sorted(iterable, key=lambda v: float(v), reverse=reverse)
          else:
            _sorted = dict(sorted(iterable.items(), key=lambda v: float(v[i]), reverse=reverse))
        else:
          raise TypeError
      except (TypeError, ValueError):
        if i is None:
          _sorted = sorted(iterable, key=lambda v: str(v), reverse=reverse)
        else:
          _sorted = dict(sorted(iterable.items(), key=lambda v: str(v[i]), reverse=reverse))

      return _sorted

    if isinstance(iterable, list):
      sorted_list = _sort(None)
      return sorted_list
    elif isinstance(iterable, tuple):
      sorted_list = tuple(_sort(None))
      return sorted_list
    elif isinstance(iterable, dict):
      if sort_on == 'keys':
        sorted_dict = _sort(0)
        return sorted_dict
      elif sort_on == 'values':
        sorted_dict = _sort(1)
        return sorted_dict
      elif sort_on is not None:
        raise ValueError(f"Unexpected value {sort_on} for sort_on. When sorting a dict, use key or values")
    else:
      raise TypeError(f"Unexpected type {type(iterable)} for iterable. Expected a list, tuple, or dict")

9

以下は、zip on d.values()およびd.keys()を使用したソリューションです。このリンクの下の数行(ディクショナリビューオブジェクト上)は次のとおりです。

これにより、zip()を使用して(値、キー)ペアを作成できます:ペア= zip(d.values()、d.keys())。

したがって、以下を実行できます。

d = {'key1': 874.7, 'key2': 5, 'key3': 8.1}

d_sorted = sorted(zip(d.values(), d.keys()))

print d_sorted 
# prints: [(5, 'key2'), (8.1, 'key3'), (874.7, 'key1')]

9

もちろん、覚えておいてください。OrderedDict通常のPython辞書は元の順序を保持しないため、使用する必要があります。

from collections import OrderedDict
a = OrderedDict(sorted(originalDict.items(), key=lambda x: x[1]))

Python 2.7以降がない場合は、ジェネレーター関数の値を反復するのが最善の方法です。(あるOrderedDict2.4および2.6のため 、ここではなく、

a)それがどれほどうまく機能するか私は知りません

そして

b)もちろん、ダウンロードしてインストールする必要があります。管理者権限がない場合は、オプションが無効になっています。)


def gen(originalDict):
    for x, y in sorted(zip(originalDict.keys(), originalDict.values()), key=lambda z: z[1]):
        yield (x, y)
    #Yields as a tuple with (key, value). You can iterate with conditional clauses to get what you want. 

for bleh, meh in gen(myDict):
    if bleh == "foo":
        print(myDict[bleh])

すべての値を印刷することもできます

for bleh, meh in gen(myDict):
    print(bleh, meh)

Python 3.0以降を使用していない場合は、印刷後にかっこを必ず削除してください


通常のPython辞書は元の順序を維持しません — Python 3.7以降は維持します。
ヘリット・

7

dictsからValueSortedDictを使用します

from dicts.sorteddict import ValueSortedDict
d = {1: 2, 3: 4, 4:3, 2:1, 0:0}
sorted_dict = ValueSortedDict(d)
print sorted_dict.items() 

[(0, 0), (2, 1), (1, 2), (4, 3), (3, 4)]

6

これは3.1.xで機能します。

import operator
slovar_sorted=sorted(slovar.items(), key=operator.itemgetter(1), reverse=True)
print(slovar_sorted)

6

Python for Everybodyから関連するスキルを学びました。

辞書を並べ替えるのに役立つ一時リストを使用できます。

#Assume dictionary to be:
d = {'apple': 500.1, 'banana': 1500.2, 'orange': 1.0, 'pineapple': 789.0}

# create a temporary list
tmp = []

# iterate through the dictionary and append each tuple into the temporary list 
for key, value in d.items():
    tmptuple = (value, key)
    tmp.append(tmptuple)

# sort the list in ascending order
tmp = sorted(tmp)

print (tmp)

リストを降順に並べ替えるには、元の並べ替え行を次のように変更します。

tmp = sorted(tmp, reverse=True)

リスト内包表記を使用すると、1つのライナーは次のようになります。

#Assuming the dictionary looks like
d = {'apple': 500.1, 'banana': 1500.2, 'orange': 1.0, 'pineapple': 789.0}
#One liner for sorting in ascending order
print (sorted([(v, k) for k, v in d.items()]))
#One liner for sorting in descending order
print (sorted([(v, k) for k, v in d.items()], reverse=True))

出力例:

#Asending order
[(1.0, 'orange'), (500.1, 'apple'), (789.0, 'pineapple'), (1500.2, 'banana')]
#Descending order
[(1500.2, 'banana'), (789.0, 'pineapple'), (500.1, 'apple'), (1.0, 'orange')]

これは、値ではなくキーで並べ替えます。
Rubel

それを初期形式で印刷したい場合は、次のようにします:print([(k、v)for v、k in sorted([(v、k)for k、v in d.items()])]))。出力は、[( 'orange'、1.0)、( 'apple'、500.1)、( 'pineapple'、789.0)、( 'banana'、1500.2)]です。[(k、v)for v、k in Sorted([(v、k)for k、v in d.items()]、reverse = True)]の場合、出力は[( 'banana'、1500.2)、 ( 'pineapple'、789.0)、( 'apple'、500.1)、( 'orange'、1.0)]
エルメスモラレス

5

dictを反復処理し、その値で降順に並べ替えます。

$ python --version
Python 3.2.2

$ cat sort_dict_by_val_desc.py 
dictionary = dict(siis = 1, sana = 2, joka = 3, tuli = 4, aina = 5)
for word in sorted(dictionary, key=dictionary.get, reverse=True):
  print(word, dictionary[word])

$ python sort_dict_by_val_desc.py 
aina 5
tuli 4
joka 3
sana 2
siis 1


5

完全を期すため、私はheapqを使用したソリューションを投稿しています。このメソッドは数値と非数値の両方で機能することに注意してください

>>> x = {1: 2, 3: 4, 4:3, 2:1, 0:0}
>>> x_items = x.items()
>>> heapq.heapify(x_items)
>>> #To sort in reverse order
>>> heapq.nlargest(len(x_items),x_items, operator.itemgetter(1))
[(3, 4), (4, 3), (1, 2), (2, 1), (0, 0)]
>>> #To sort in ascending order
>>> heapq.nsmallest(len(x_items),x_items, operator.itemgetter(1))
[(0, 0), (2, 1), (1, 2), (4, 3), (3, 4)]

4

古いバージョンのPythonとの下位互換性を維持する必要があるため、OrderedDictソリューションは非常に賢明ではないと思います。Python 2.7以前のバージョンで動作するものが必要です。

しかし、別の回答で述べられているコレクションソリューションは、辞書の場合に非常に重要なキーと値の間の接続を再トレーニングするため、非常に優れています。

別の答えで提示された一番の選択肢には同意しません。それは鍵を捨ててしまうからです。

私は上記のソリューション(以下に示すコード)を使用し、キーと値の両方へのアクセスを保持しました。私の場合、順序は値に基づいていましたが、重要なのは値の順序後のキーの順序です。

from collections import Counter

x = {'hello':1, 'python':5, 'world':3}
c=Counter(x)
print c.most_common()


>> [('python', 5), ('world', 3), ('hello', 1)]
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.