This site is an archive of ama.ne.jp.

dict_keysの話

Python文法詳解で次のような記述を見ました。

dict.keys()メソッドは、キーのビューオブジェクトを返します。ビューオブジェクトは集合オブジェクトに似たイテラブルオブジェクトで、全てのキーを列挙したり、要素の存在チェックを行ったりできます。(コード例略)他の集合やイテラブルオブジェクトと、集合演算も行えます。

コード例ではリストとの減算しか行っていなかったので、いろいろやってみることにしたのですが……。

dictionary = {1: 'spam', 2: 'ham', 3: 'egg'}
dictionary.keys()

dictionary.keys() - [1, 2]
dictionary.keys() + [1, 2]

dictionary.keys() - {1, 2}
dictionary.keys() + {1, 2}

dictionary.keys() - (1, 2)
dictionary.keys() + (1, 2)

適当な辞書とリスト、セット、タプルとの演算のテストコードです。結果を見てみましょう。

>>> dictionary.keys() - [1, 2]
{3}
>>> dictionary.keys() + [1, 2]
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>;
TypeError: unsupported operand type(s) for +: 'dict_keys' and 'list'

>>> dictionary.keys() - {1, 2}
{3}
>>> dictionary.keys() + {1, 2}
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unsupported operand type(s) for +: 'dict_keys' and 'set'

ここまで、2つのイテラブルオブジェクトとの演算により、dict_keysがイテラブルオブジェクトに対して減算を定義していることが予測できます。

しかし、タプルとの演算では、謎のエラーに悩まされることになったのでした。

>>> dictionary.keys() - (1, 2)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>;
TypeError: 'int' object is not iterable
>>> dictionary.keys() + (1, 2)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>;
TypeError: unsupported operand type(s) for +: 'dict_keys' and 'tuple'

dict_keysとタプルの間の減算でもエラーが発生してしまいます。

タプルがどうこういう問題の前にタプルの要素である整数型のオブジェクトが呼ばれているらしく。

Python-forumで質問してみても、どうも納得できる回答は得られず。

Subtraction tuple from dict.keys()1

3つのビルトインのイテラブルオブジェクトには、どういう関係があるんでしょうね。どなたか知ってる方がいらっしゃったら、教えてもらえれば幸いです。


  1. http://www.python-forum.org/viewtopic.php?f=10&t=16998