web-dev-qa-db-ja.com

Pythonのキーで辞書をソートする方法

誰も私がこれをソートする方法を教えてもらえますか:

{'a': [1, 2, 3], 'c': ['one', 'two'], 'b': ['blah', 'bhasdf', 'asdf'], 'd': ['asdf', 'wer', 'asdf', 'zxcv']}

{'a': [1, 2, 3], 'b': ['blah', 'bhasdf', 'asdf'], 'c': ['one', 'two'],'d': ['asdf', 'wer', 'asdf', 'zxcv']}

?ありがとう!

更新1、コードサンプル:

だから私は言語学をやっています。 1つの記事は、データベースに保存され、パラIDやセンテンスIDを含むあらゆる種類のプロパティを持つ単語に分類されます。タスク:元のテキストを再構築しようとしています。

DBから500連続ワードを取得

words = Words.objects.all()[wordId:wordId+500]
# I first create paragraphs, through which I can loop later in my Django template,
# and in each para will be a list of words (also dictionaries). 
# So i am trying to get a dictionary with values that are lists of dictionaries. 
# 'pp' i make just for shorthanding a long-named variable.
paras={}
para_high = para_low =  words[0].belongs_to_paragraph
for w in words:
    last_Word = w
    pp = w.belongs_to_paragraph
    if pp >para_high:
        para_high = pp
    if pp < para_low:
        para_low = pp
    if pp in paras:
        paras[pp].append(w)
    else:
        list = [w]
        paras[pp] = list
# Since there are blank lines between paragraphs, in rebuilding the text as it 
    #  looked originally, I need to insert blank lines. 
    # Since i have the ID's of the paragraphs and they go somewhat like that: 1,3,4,8,9 
    #(the gaps between 1 & 3 and 4 & 8 i have to fill in with something else, 
    # which is why i had para_low and para_high to loop the range. 
isbr = True
for i in range(para_low, para_high+1):
    if i in paras:
        isbr = True
    else:
        if isbr:
            paras[i]=['break']
            isbr = False
        else:
            paras[i]=[]

ただし、この時点で、辞書をループしてテキストを再構築しようとすると、後でidが指定された段落が前の段落の前に来るため、それが実行されません。

更新2、ループコード:

        {% for k,v in wording.iteritems()  %}
        {% if v[0] == 'break' %}
        <br/>
        {% else %}
        </div><div class="p">{% for Word in v %}{% if Word.special==0%} {% endif %}<span class="Word {% if Word.special == 0%}clickable{% endif%}" wid="{{Word.id}}" special="{{Word.special}}" somethingElse={{Word.somethingElse}}>{{ Word.word }}</span>{% endfor %}
        {% endif %}
    {% endfor %}
18
mgPePe

辞書には順序がありません。

ソート済みを呼び出すことができますが、これはキーのソート済みリストを提供するだけです:

>>> sorted(d)
['a', 'b', 'c', 'd']

これを反復可能として扱い、キーと値のタプルをソートすることができますが、タプルのリストが得られました。それは辞書と同じではありません。

>>> sorted(d.items())
[
 ('a', [1, 2, 3]),
 ('b', ['blah', 'bhasdf', 'asdf']),
 ('c', ['one', 'two']),
 ('d', ['asdf', 'wer', 'asdf', 'zxcv'])
]

Python 2.7以降を使用している場合は、 OrderedDict の使用も検討できます。

追加された順序エントリを記憶するdictサブクラス

例えば:

>>> d = collections.OrderedDict(sorted(d.items()))
>>> for k, v in d.items():
>>>     print k, v
 a [1、2、3] 
 b ['blah'、 'bhasdf'、 'asdf'] 
 c ['one'、 'two'] 
 d ['asdf'、 'wer'、 'asdf'、 'zxcv'] 
46
Mark Byers

正しい答えは、ソートされた順序で辞書の項目が必要な場合、辞書をループするときに、sorted()関数を使用する必要があるということです

for k, v in sorted(d.items()):
    print k, ':', v

または

for k in sorted(d):
   print d[k]

または類似。

前述のOrderedDictは、順序を持つ辞書用です。また、順序はソートと同じではありません。ソートされたOrderedDictを作成できます(はい)が、新しいキーを追加するとすぐにソートされなくなります。 したがって、sort()を使用する必要があります使用する前または操作するたびにソートする必要があります。したがって、OrderedDictは、通常の辞書よりも低速でメモリ集約型ですが、必要なものは何も追加しません。

OrderedDictは、ソートされたディクショナリの場合はnotですが、アイテムにnotソート。追加した順序で物事を表示したい場合や、ユーザーが物事を任意に注文できるようにする場合などです。

更新:詳細な説明

OrderedDictがソリューションではないのはなぜですか? OrderedDictはorderedではなくsortedであるためです。

標準的な辞書を考えてみましょう:

>>> d = {'a': 0, 'b': 1, 'c': 2, 'd': 3, 'e': 4, 'f': 5}

以下に示すように、ソートされていません。「c」は「b」の前に来ます。また、順序はありません。新しいものを追加すると、ランダムな順序のように見えます。

>>> d['g'] = 6
>>> d['i'] = 8
>>> d
{'a': 0, 'c': 2, 'b': 1, 'e': 4, 'd': 3, 'g': 6, 'f': 5, 'i': 8}

それでは、OrderedDictを使用してみましょう。

>>> o = OrderedDict(sorted({'a': 0, 'b': 1, 'c': 2, 'd': 3, 'e': 4, 'f': 5}.items()))
>>> o
OrderedDict([('a', 0), ('b', 1), ('c', 2), ('d', 3), ('e', 4), ('f', 5)])

あぁ!ソート済み! OrderedDictは動作します!?番号。

>>> o['i'] = 8
>>> o['g'] = 6
>>> o
OrderedDict([('a', 0), ('b', 1), ('c', 2), ('d', 3), ('e', 4), ('f', 5), ('i', 8), ('g', 6)])

何? gはi?!?の後にafterなぜ!? OrderedDictはソートされていないため、orderedです。物を追加したorderを記憶します。並べ替えではありません。これは、使用するたびに最初にソートする必要があることを意味します。 OrderedDictは、キーを追加しない限りソートされたままになります。しかし、あなたがそれを修正するつもりがないなら、あなたは辞書を必要としません。リストを作成することもできます。これはsorted()から得られるものです:

>>> sorted(o.items())
[('a', 0), ('b', 1), ('c', 2), ('d', 3), ('e', 4), ('f', 5), ('g', 6), ('i', 8)]

しかし、これは標準の辞書でも同様に機能するため、OrderedDictionaryは役に立ちませんでした。

>>> sorted(d.items())
[('a', 0), ('b', 1), ('c', 2), ('d', 3), ('e', 4), ('f', 5), ('g', 6), ('i', 8)]

結論したがって、ソートされた方法で辞書をループするたびに、以下を行う必要があります。

>>> for k in sorted(o):
...   print k, o[k]
... 
a 0
b 1
c 2
d 3
e 4
f 5
g 6
i 8

そして、どの辞書を使用してもです。 OrderedDictはsortingを気にせず、order物を追加します。

29
Lennart Regebro

Pythonには、ソートされた順序でキーを保持する多くの辞書実装があります。純粋なPythonおよびfast-as-Cである sortedcontainers モジュールを検討してください。 パフォーマンスの比較 があり、他の高速で機能が完全な実装が互いにベンチマークされています。

例えば:

>>> from sortedcontainers import SortedDict
>>> d = {'a': [1, 2, 3], 'c': ['one', 'two'], 'b': ['blah', 'bhasdf', 'asdf'], 'd': ['asdf', 'wer', 'asdf', 'zxcv']}
>>> s = SortedDict(**d)
>>> s.keys()
SortedSet(['a', 'b', 'c', 'd'])

Dictの使用を SortedDict で完全に置き換えることもできます。これは、キーによる項目の高速な取得/設定操作とソートされた反復をサポートするためです。

5
GrantJ

他の答えが述べたように、辞書のキーの順序は任意であり、それに依存するべきではありません。

Python 2.7または3.1以降を使用している場合は、collections.OrderedDict2.7ドキュメント ; .1ドキュメント ; PEP 372 も参照)。ドキュメントには OrderedDictの純粋なPythonバージョン へのリンクがあります。以前のバージョンPython.

1
Nicholas Riley

他の人がすでに説明したものに1セントを加算します。特定のケースでまったく同じ問題が発生しました。安定した単体テストを作成するために、辞書の出力が常に同じである必要がありました。

偶然それがあなたが達成しようとしているもの、または他の出力関連のタスクである場合、何もソートする必要はありません。単にpprintモジュールを使用してください。

>>> d = {'a':1, 'b':2, 'c':3}
>>> print d
{'a': 1, 'c': 3, 'b': 2}

>>> from pprint import pprint
>>> pprint(d)
{'a': 1, 'b': 2, 'c': 3}
0
kriss

以下に、キーで辞書をソートするために使用できる迅速で簡単な機能を示します。

このコードをsdict.pyという別のファイルに入れます。

def sortdict(dct):
    kys = dct.keys()
    kys.sort()
    from collections import OrderedDict
    d = OrderedDict()
    for x in kys: 
        for k, v in dct.iteritems():
            if (k == x):
                d[k] = v
    return d

次に、このコードをtest.pyという別のファイルに配置して、サンプル辞書でテストします。

from sdict import sortdict
import json
dct = {'sizes':[32,28,42], 'dog':'schnauser', 'cat':'siamese', 'bird':'falcon'}
dctx = sortdict(dct)
print json.dumps(dctx) 

最後に、コマンドラインからtest.pyを呼び出します:

$ python test.py
{"bird": "falcon", "cat": "siamese", "dog": "schnauser", "sizes": [32, 28, 42]}

Json.dumps行のみを使用して、文字列表現ではなく、実際の辞書であることを示しています。また、type()関数でテストすることもできます。

サンプル辞書に数値を含むネストされたリストを含めて、関数が単一レイヤーの文字列ベースの辞書ではなく、より複雑な辞書を処理できることを示しました。

コードは非常に単純なので、それが好みであれば値でソートするように変更するのは簡単です-値のソートはリスト、タプルまたは他の辞書のようなオブジェクトである場合は意味がありませんが。

確かに、これはpython 2.7以降でのみ動作します。

乾杯、
-=キャメロン

0
Cameron Landers

Heapqで最も大きいnルーチンに言及する価値もあります。これは、上位N個のアイテムをソートして返します。実際に何が必要かによっては、keyパラメーターを使用する場合に便利です。私が数晩前にそれを発見したので、私は主にこれに言及します、そして、それはまさに私がそうであったことをしました。 PEP 0265 および Heapq を参照してください。

0
dave