web-dev-qa-db-ja.com

dictからOrderedDictへの変換

collections.OrderedDictクラスの使用に問題があります。 Raspberry PiのDebianディストリビューションであるRaspbianでPython 2.7を使用しています。テキストアドベンチャーの比較(並べて)のために、2つの辞書を印刷しようとしています。順序は正確に比較するために不可欠です。私が何を試しても、辞書は通常の順序なしに印刷されます。

RPiで行うと、次のようになります。

import collections

ship = {"NAME": "Albatross",
         "HP":50,
         "BLASTERS":13,
         "THRUSTERS":18,
         "PRICE":250}

ship = collections.OrderedDict(ship)

print ship
# OrderedDict([('PRICE', 250), ('HP', 50), ('NAME', 'Albatross'), ('BLASTERS', 13), ('THRUSTERS', 18)])

関数呼び出しを出力し、キーと値グループをネストされたリストに入れているため、明らかに正しくないものがあります...

これは私のPCで似たようなものを実行することで得たものです:

import collections

Joe = {"Age": 28, "Race": "Latino", "Job": "Nurse"}
Bob = {"Age": 25, "Race": "White", "Job": "Mechanic", "Random": "stuff"}

#Just for clarity:
Joe = collections.OrderedDict(Joe)
Bob = collections.OrderedDict(Bob)

print Joe
# OrderedDict([('Age', 28), ('Race', 'Latino'), ('Job', 'Nurse')])
print Bob
# OrderedDict([('Age', 25), ('Race', 'White'), ('Job', 'Mechanic'), ('Random', 'stuff')])

今回は順番に並んでいますが、他のことを印刷してはいけません。 (リストに入れて、関数呼び出しを表示します。)

エラーはどこで発生しますか? Linuxバージョンであるため、Pythonのpiバージョンとは関係ありません。

110
pythonpiboy

辞書を作成しfirst、次にその辞書をOrderedDictに渡します。 Pythonバージョン<3.6の場合 (*)、それを行うまでに、順序は正しくなくなります。 dictは本質的に順序付けられていません。

代わりに、一連のタプルを渡します。

ship = [("NAME", "Albatross"),
        ("HP", 50),
        ("BLASTERS", 13),
        ("THRUSTERS", 18),
        ("PRICE", 250)]
ship = collections.OrderedDict(ship)

OrderedDictを印刷すると、表示されるのはrepresentationであり、完全に正しいです。 OrderedDict([('PRICE', 250), ('HP', 50), ('NAME', 'Albatross'), ('BLASTERS', 13), ('THRUSTERS', 18)])は、reproducable表現で、OrderedDictの内容を表示するだけです。


(*):CPython 3.6の実装では、dict型が更新され、挿入順序を維持するという副作用があり、メモリ効率の高い内部構造が使用されるようになりました。 Python 3.7の時点で、Python言語仕様が更新され、すべてのPython実装に従う必要があります。この振る舞い。詳細と、特定の場合にOrderedDict()を使用する必要がある理由については、 この他の回答 を参照してください。

181
Martijn Pieters

Dictが定義されたコードのこの部分を編集できない場合でも、次のように、いつでも好きな方法でそれを注文できます。

from collections import OrderedDict

order_of_keys = ["key1", "key2", "key3", "key4", "key5"]
list_of_tuples = [(key, your_dict[key]) for key in order_of_keys]
your_dict = OrderedDict(list_of_tuples)
21
Jan Rozycki

ほとんどの場合、ASCなどの一般的な注文ではなくカスタム注文が必要な場合は、OrderedDictを使用します。

提案されたソリューションは次のとおりです。

import collections
ship = {"NAME": "Albatross",
         "HP":50,
         "BLASTERS":13,
         "THRUSTERS":18,
         "PRICE":250}

ship = collections.OrderedDict(ship)

print ship


new_dict = collections.OrderedDict()
new_dict["NAME"]=ship["NAME"]
new_dict["HP"]=ship["HP"]
new_dict["BLASTERS"]=ship["BLASTERS"]
new_dict["THRUSTERS"]=ship["THRUSTERS"]
new_dict["PRICE"]=ship["PRICE"]


print new_dict

これは出力されます:

OrderedDict([('PRICE', 250), ('HP', 50), ('NAME', 'Albatross'), ('BLASTERS', 13), ('THRUSTERS', 18)])
OrderedDict([('NAME', 'Albatross'), ('HP', 50), ('BLASTERS', 13), ('THRUSTERS', 18), ('PRICE', 250)])

:エントリが削除されると、新しいソートされた辞書はソート順を維持します。しかし、新しいキーが追加されると、キーは最後に追加され、ソートは維持されません。( official doc

8
Abdul Majeed