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


Answers

同じように単純に: 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)を使用頻度でsorted(d, key=d.get)られた単語のリストを取得できます。ソートキーとして単語の出現回数を使用して、ソートは辞書キーを繰り返します。

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

私はこの詳細な説明を書いて、「キーで辞書を簡単に並べ替えることはできますが、値で並べ替えるにはどうすればよいですか」ということをよく説明しています。OPはそのような問題に対処しようとしていたと思います。 そして、解決策は、上記のように、値に基づいてキーの並べ替えを行うことです。

Question

私はデータベースの2つのフィールドから読み込まれた値の辞書を持っています:文字列フィールドと数値フィールド。 文字列フィールドはユニークなので、辞書のキーです。

私はキーを並べ替えることができますが、値に基づいてどのようにソートできますか?

注:私はの質問を読んでいます。 辞書のリストをPythonの辞書の値で並べ替えるにはどうすればいいですか? おそらく辞書のリストを持つように私のコードを変更することができますが、私は実際に辞書のリストを必要としないので、より単純な解決策があるかどうかを知りたいと思っていました。




Dictsはソートすることはできませんが、ソートされたリストを作成することはできます。

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

sorted(d.values())

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

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



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


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

または、John Fouhyの提案どおりに最適化してください。


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




値が整数で、Python 2.7以降を使用する場合は、 dict代わりにcollections.Counterを使用できます。 most_commonメソッドは、値でソートされたすべてのアイテムを表示します。




これは、値が高い順にソートされた辞書のキーと値のペアのリストを返します。

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

キーでソートされた辞書の場合は、次のようにします。

sorted(d.items(), reverse=True)

辞書自体はソートできないため、戻り値はタプルのリストです。

これは、印刷されるか、またはさらなる計算に送られる。




値が数値の場合は、コレクションからカウンタを使用することもできます

from collections import Counter

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


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



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

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

Python 2.7以上を使用していない場合、できることはジェネレータ関数の値を繰り返し処理することです。 (ここには2.4と2.6のOrderedDictがありますが、

a) I don't know about how well it works 

そして

b) You have to download and install it of course. If you do not have administrative access, then I'm afraid the option's out.)
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以降を使用していない場合は、印刷後に括弧を削除してください




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

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)

もう1つの方法はlabmda関数を使用することです

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



ここでは、 d.values()およびd.keys() zipを使用するソリューションを示します。 このリンクの下のいくつかの行(辞書ビューオブジェクト上)は次のとおりです:

これにより、zip():pairs = 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')]



私はこれを思いついた。

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

Python 3.xの場合: x.items()置き換えるiteritems()

>>> sorted_x
{0: 0, 1: 2, 2: 1, 3: 4, 4: 3}

またはcollections.OrderedDict試してみてください!

x = {1: 2, 3: 4, 4:3, 2:1, 0:0}
from collections import OrderedDict

od1 = OrderedDict(sorted(x.items(), key=lambda t: t[1]))



なぜこのアプローチを試してみませんか? 以下のデータを持つ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



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

受け入れられた答えが有用であることが判明したOrderedDict 、このタイプの問題を正確に解決するために設計された、現実的で現代的な代替手段として、標準ライブラリコレクションモジュールからOrderedDictを参照する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)])



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 : http://docs.python.org/dev/library/collections.html#ordereddict-examples-and-recipes

楽しい ;-)




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)])



与えられた辞書

e = {1:39, 4:34, 7:110, 2:87}

並べ替え

sred = sorted(e.items(), key=lambda value: value[1])

結果

[(4, 34), (1, 39), (2, 87), (7, 110)]

ラムダ関数を使用して、値でソートし、変数(この場合はオリジナルの辞書であるsred)内で処理します。

希望が助けてくれる!