web-dev-qa-db-ja.com

辞書とOrderedDictの違い

ソートされた辞書を取得しようとしています。しかし、mydictorddictの間のアイテムの順序は変更されていないようです。

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)
13
liv2hak

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

したがって、OrderedDictorder要素を提供しません。preserves提供する順序を提供します。

辞書を「ソート」したい場合は、おそらく

>>> sorted(d.items())
[('a', 1), ('b', 2), ('c', 3)]
11
Brian Malehorn

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}
3
Mike T

順序付き辞書は通常の辞書と同じですが、アイテムが挿入された順序を記憶しています。順序付けされたディクショナリを反復する場合、項目は、キーが最初に追加された順序で返されます。

そのため、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]))

詳細は 8.3.5.1。OrderedDictの例とレシピ

3
neo

ブライアンの答えに加えて、OrderedDictは本当に素晴らしいです。理由は次のとおりです。

  • collections.counter のような他のdictオブジェクトとの同等性テストをサポートするため、単純なMappingオブジェクトとして使用できます。

  • OrderedDictは、ブライアンが説明したように挿入順序を保持します。それに加えて、メソッド popitem は(キー、値)のペアをLIFOの順序で返します。したがって、マップされた「スタック」としても使用できます。 。

dictの完全な機能だけでなく、いくつかのクールなトリックも利用できます。

3
xssChauhan

OrderedDictのドキュメント (私の強調)から:

dictとのいくつかの違いはまだ残っています:

  • 通常のdictは、マッピング操作が非常にうまくできるように設計されています。広告掲載オーダーのトラッキングは二次的なものでした。

  • OrderedDictは、操作の並べ替えに優れているように設計されています。スペース効率、反復速度、および更新操作のパフォーマンスは二次的なものでした。

  • アルゴリズム的には、OrderedDictは、頻繁な並べ替え操作をdictよりも適切に処理できます。これにより、最近のアクセスの追跡に適しています(たとえば、 LRUキャッシュ 内)。

  • OrderedDictの等価演算は、一致する順序をチェックします

  • popitemOrderedDictメソッドには、異なる署名があります。オプションの引数を受け入れて、ポップするアイテムを指定します。

  • OrderedDictには、要素をエンドポイントに効率的に再配置するmove_to_endメソッドがあります。

  • Python 3.8まで、dictには__reversed__メソッドがありませんでした。

1
Boris