[Python] 辞書の要素の順番を保持する(OrderedDict)

Python モジュール 組込み型 辞書型

Python3.6時点では辞書データはリストと異なり要素の順番は不定です。辞書型のデータ構造で順番を維持させたい場合はcollections.OrderedDict()を使います。このメソッドで生成される順序付き辞書(Ordered dictionary)は、データが登録された順序が保持されます。今回はこのOrderedDict()メソッドの使い方についてまとめます。
(2018.7.1更新) Python3.7から辞書データの順番が保持されることが仕様化されました。

確認した環境

OS: Ubuntu 16.04LTS
Python: ver3.6.4

辞書における要素の順番について

Python3.6から辞書の挿入順番が保持される実装が追加されていますが、まだ言語(Python)としての仕様化までには至っていません。公式ドキュメントにも「それに頼るべきではない」と記載があります。正式にはPython3.7からサポートされるとの議論がありますが、今は順序付き辞書(Ordered dictionary)を使うべきだそうです。
確認してみると、、確かにPthon3.5とPython3.6で挙動が変わっています。
(2018.7.1更新)Python3.7がリリースされ、辞書の挿入順番が保持されることが正式に仕様化されました。

バージョン 3.7 で変更: Dictionary order is guaranteed to be insertion order. This behavior was implementation detail of CPython from 3.6.

公式ドキュメント

Python 3.5.2 (default, Nov 23 2017, 16:37:01) 
[GCC 5.4.0 20160609] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> dic = {}
>>> dic['a'] = 1
>>> dic['b'] = 2
>>> dic['c'] = 3
>>> dic['d'] = 4
>>> dic
{'d': 4, 'a': 1, 'c': 3, 'b': 2}
>>> for k, v in dic.items():
...     print(k, v)
... 
d 4
a 1
c 3
b 2
>>> 

Python 3.6.4 |Anaconda custom (64-bit)| (default, Dec 21 2017, 21:42:08) 
[GCC 7.2.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> dic = {}
>>> dic['a'] = 1
>>> dic['b'] = 2
>>> dic['c'] = 3
>>> dic['d'] = 4
>>> dic
{'a': 1, 'b': 2, 'c': 3, 'd': 4}
>>> for k, v in dic.items():
...     print(k, v)
... 
a 1
b 2
c 3
d 4
>>> 

順序付き辞書(Ordered dictionary)の使い方

順序付き辞書 (ordered dictionary) は以下で定義されます。

class collections.OrderedDict([items])

このメソッドはデータが挿入された順序を保持します。順序付き辞書のデータを順次読み出すと、追加された順番に出力されます。

>>> from collections import OrderedDict #collectionsモジュールをインポート
>>> dic = OrderedDict()   #順序付き辞書を定義
>>> dic['a'] = 4
>>> dic['b'] = 3
>>> dic['c'] = 2
>>> dic['d'] = 1
>>> dic

#順番が保持されているか確認
>>> for k, v in dic.items(): 
...     print(k, v)
... 
a 4
b 3
c 2
d 1

既存のキーの値を上書き更新した場合は順番は変わらないままです。

>>> dic['b'] = 7 #キーが'b'の値を更新
>>> for k, v in dic.items():
...     print(k, v)
... 
a 4
b 7
c 2
d 1

また、キーを削除して再度追加した場合は、順番の最後に移動します。

#キーが'b'のデータを削除
>>> del dic['b']
	
#削除されていることを確認
>>> dic
OrderedDict([('a', 4), ('c', 2), ('d', 1)])

#同じキーのデータを再度挿入
>>> dic['b'] = 10

#上記で追加したデータは最後に移動
>>> for k, v in dic.items():
...     print(k, v)
... 
a 4
c 2
d 1
b 10

まとめ

  • Python3.6では辞書に順番を保持する実装が追加されたが、まだ言語として仕様化されていません。よって、データの挿入順番を保持したい場合は、順序付き辞書(Ordered dictionary)を使います。(将来(Python3.7?)では対応されるかも)
  • Python3.7から挿入順番を保持することが仕様化されました。(旧バージョンとの互換を考えるとしばらくはOrderedDictを使ったほうがよいかも?)

参考書籍

書籍でもう少し詳しく学びたい場合はこちらもどうぞ。筆者もかなり参考にさせてもらっています!

シェアする
ひびきをフォローする
Hbk project