Python
python3

OrderedDictのコンストラクタの挙動

最近、OrderedDictを久しぶりに使おうと思ったときに、
「コンストラクタの挙動に注意しないといけないんだっけ」っていうのが頭にあって、
ググるとそんな風な日本語の記事を多く見かけたが、
念のためにドキュメントを読んだら、3.6でその挙動が変更されていた。

Changed in version 3.6: With the acceptance of PEP 468,
order is retained for keyword arguments passed to
the OrderedDict constructor and its update() method.

引用:python3.6ドキュメント

コード

from collections import OrderedDict

od = OrderedDict(
    a=0,
    b=1,
    c=2
)
print(''.join(od))

期待する出力は abc

実行結果

3.6.2

~/G/B/o/3.6 ❯❯❯ python od_constract.py
abc
~/G/B/o/3.6 ❯❯❯ python od_constract.py
abc
~/G/B/o/3.6 ❯❯❯ python od_constract.py
abc
~/G/B/o/3.6 ❯❯❯ python od_constract.py
abc
~/G/B/o/3.6 ❯❯❯ python od_constract.py
abc

abcの順序で出力される

3.5.3

~/G/B/o/3.5 ❯❯❯ python od_constract.py
cab
~/G/B/o/3.5 ❯❯❯ python od_constract.py
bca
~/G/B/o/3.5 ❯❯❯ python od_constract.py
acb
~/G/B/o/3.5 ❯❯❯ python od_constract.py
abc
~/G/B/o/3.5 ❯❯❯ python od_constract.py
acb

abc以外の並びが出力される

2.7.13

~/G/B/o/2.7 ❯❯❯ python od_constract.py
acb
~/G/B/o/2.7 ❯❯❯ python od_constract.py
acb
~/G/B/o/2.7 ❯❯❯ python od_constract.py
acb
~/G/B/o/2.7 ❯❯❯ python od_constract.py
acb
~/G/B/o/2.7 ❯❯❯ python od_constract.py
acb

なぜかacbの並びで出力される

The OrderedDict constructor and update() method both accept keyword arguments,
but their order is lost because Python’s function call semantics pass-in
keyword arguments using a regular unordered dictionary.

引用:python2.7ドキュメント

まとめ

3.6を使いましょう!