ソートされた辞書を取得しようとしています。しかし、mydict
とorddict
の間のアイテムの順序は変更されていないようです。
from collections import OrderedDict
mydict = {'a': 1, 'b': 2, 'c': 3, 'd': 4}
orddict = OrderedDict(mydict)
print(mydict, orddict)
# print items in mydict:
print('mydict')
for k, v in mydict.items():
print(k, v)
print('ordereddict')
# print items in ordered dictionary
for k, v in orddict.items():
print(k, v)
# print the dictionary keys
# for key in mydict.keys():
# print(key)
# print the dictionary values
# for value in mydict.values():
# print(value)
OrderedDict
は、挿入された順序要素を保持します。
>>> od = OrderedDict()
>>> od['c'] = 1
>>> od['b'] = 2
>>> od['a'] = 3
>>> od.items()
[('c', 1), ('b', 2), ('a', 3)]
>>> d = {}
>>> d['c'] = 1
>>> d['b'] = 2
>>> d['a'] = 3
>>> d.items()
[('a', 3), ('c', 1), ('b', 2)]
したがって、OrderedDict
はorder要素を提供しません。preserves提供する順序を提供します。
辞書を「ソート」したい場合は、おそらく
>>> sorted(d.items())
[('a', 1), ('b', 2), ('c', 3)]
Python 3.7 以降、新しい改善点は次のとおりです。
dictオブジェクトの挿入順保持の性質は、Python言語仕様の公式の一部であると宣言されています。
これは、OrderedDictの必要性がなくなったことを意味します。彼らはほとんど同じです。ただし、注意すべき違いがあります。
from collections import OrderedDict
d = {'b': 1, 'a': 2}
od = OrderedDict([('b', 1), ('a', 2)])
# they are equal with content and order
assert d == od
assert list(d.items()) == list(od.items())
assert repr(dict(od)) == repr(d)
明らかに、2つのオブジェクトの文字列表現には違いがあり、dict
オブジェクトはより自然でコンパクトな形式になっています。
2つの方法の違いについては、この質問は集合論で答えることができます。
d_set = set(dir(d))
od_set = set(dir(od))
od_set.difference(d_set)
# {'__dict__', '__reversed__', 'move_to_end'}
つまり、OrderedDict
にはdict
に組み込まれていない機能が少なくとも2つありますが、回避策を次に示します。
# 1) OrderedDict can be reversed (but then what?)
reversed(od)
# <odict_iterator at 0x7fc03f119888>
reversed(d)
# TypeError: 'dict' object is not reversible
# better way to reverse a dict
dict(reversed(list(d.items()))) # {'a': 2, 'b': 1}
# 2) OrderedDict has 'move_to_end' method
od.move_to_end('b') # now it is: OrderedDict([('a', 2), ('b', 1)])
# dict does not, but similar can be done with
d['b'] = d.pop('b') # now it is: {'a': 2, 'b': 1}
順序付き辞書は通常の辞書と同じですが、アイテムが挿入された順序を記憶しています。順序付けされたディクショナリを反復する場合、項目は、キーが最初に追加された順序で返されます。
そのため、dictに追加する順序でのみ並べ替えます
次のように、キーによってOrderedDict注文を作成できます。
orddict = OrderedDict(sorted(mydict.items(), key = lambda t: t[0]))
または単にコメントで@ShadowRangerが言及したとおり
orddict = OrderedDict(sorted(d.items()))
値で注文したい場合は、
orddict = OrderedDict(sorted(mydict.items(), key = lambda t: t[1]))
ブライアンの答えに加えて、OrderedDict
は本当に素晴らしいです。理由は次のとおりです。
collections.counter のような他のdict
オブジェクトとの同等性テストをサポートするため、単純なMapping
オブジェクトとして使用できます。
OrderedDict
は、ブライアンが説明したように挿入順序を保持します。それに加えて、メソッド popitem は(キー、値)のペアをLIFOの順序で返します。したがって、マップされた「スタック」としても使用できます。 。
dict
の完全な機能だけでなく、いくつかのクールなトリックも利用できます。
OrderedDict
のドキュメント (私の強調)から:
dict
とのいくつかの違いはまだ残っています:
通常の
dict
は、マッピング操作が非常にうまくできるように設計されています。広告掲載オーダーのトラッキングは二次的なものでした。
OrderedDict
は、操作の並べ替えに優れているように設計されています。スペース効率、反復速度、および更新操作のパフォーマンスは二次的なものでした。アルゴリズム的には、
OrderedDict
は、頻繁な並べ替え操作をdict
よりも適切に処理できます。これにより、最近のアクセスの追跡に適しています(たとえば、 LRUキャッシュ 内)。
OrderedDict
の等価演算は、一致する順序をチェックします。
popitem
のOrderedDict
メソッドには、異なる署名があります。オプションの引数を受け入れて、ポップするアイテムを指定します。
OrderedDict
には、要素をエンドポイントに効率的に再配置するmove_to_end
メソッドがあります。Python 3.8まで、
dict
には__reversed__
メソッドがありませんでした。