辞書と順序付き辞書
Python 3.5 までは辞書型オブジェクトには順序が保持されていませんでしたが、
Python 3.6 から順序付き辞書型(OrderedDict) で順序が保持されるようになりました。
これまでの辞書型オブジェクトでの挿入順序を記憶しておく機能については実装依存で、Pythonの言語仕様としては保証されていませんでしたが、Python3.7で保証されるようになります。
では、辞書型(dict)オブジェクトと順序付き辞書型(OrderedDict)オブジェクトとをどう使い分ければよいのでしょうか?
まず、この2つの型は設計方針が異なっていることを理解しましょう。
dict は対応付けに向くように設計されている。
挿入順序の追跡は考慮していない。
OrderedDict は 並べ替え操作に向くように設計されている。
空間効率、反復処理の速度、更新操作のパフォーマンスは考慮していない。
アルゴリズム的に OrderedDict は高頻度の並べ替え操作を dict よりも上手く扱うことができるようになっています。
OrderedDict は直近のアクセスの追跡に向いている。
他に、次のような違いがあります。
OrderedDict に対する等価演算は突き合わせ順序もチェックする。
OrderedDict の popitem() メソッドは実装が異なる。
どの要素を取り出すかを指定するオプション引数を受け付ける。
OrderedDict には、 効率的に要素を末尾に置き直す move_to_end() メソッドがある。
とくに、popitem() メソッドは実装方法が違っています。機能としては辞書オブジェクトの要素を削除して、その要素を返します。辞書型(dict)では取り出す要素を指定することはできませんが、順序付き辞書型(OrderedDict)では、FIFO(First-In First-Out: 先入れ先出し) あるいは LIFO(Last-In First-Out: 後入れ先出し)で要素の方向を指定をするオプション last=<True|False>を取ることができます。
code: 0222_ordereddict.py
from collections import OrderedDict
d = {'b': 1, 'a': 2, 'c':3}
k,v=d.popitem()
print(type(d))
print(k,v)
print(d.items())
k,v=od.popitem(last=False)
print(type(od))
print(k,v)
print(od.items())
k,v=od.popitem(last=True)
print(type(od))
print(k,v)
print(od.items())
実行して確かめてみましょう。
code: bash
$ python 0222_ordereddict.py
<class 'dict'>
c 3
<class 'collections.OrderedDict'>
b 1
<class 'collections.OrderedDict'>
c 3