1. ホーム
  2. python

[解決済み] Pythonでリストをdictのキーとして使えないのはなぜですか?

2022-08-14 10:55:15

質問

Pythonのdictのキーとして何が使えるのか、使えないのか、少し混乱しています。

dicked = {}
dicked[None] = 'foo'     # None ok
dicked[(1,3)] = 'baz'    # tuple ok
import sys
dicked[sys] = 'bar'      # wow, even a module is ok !
dicked[(1,[3])] = 'qux'  # oops, not allowed

タプルは不変の型ですが、その中にリストを隠すとキーにならないのですね。同じように簡単にモジュールの中にリストを隠すことはできないのでしょうか?

キーが "hashable" でなければならないという漠然とした考えは持っていましたが、技術的な詳細については私自身の無知を認めることにします。 ハッシュをたとえばメモリの場所として、リストをキーとして使用しようとした場合、何がうまくいかないのでしょうか?

どのように解決するのですか?

Pythonのwikiにこのトピックに関する良い記事があります。 なぜリストは辞書のキーになりえないのか . そこで説明されているように

もしあなたがリストをキーとして、ハッシュをそのメモリ位置として使おうとしたら、何が問題なのでしょうか?

それは本当にどの要件も破ることなく行うことができますが、予期しない動作につながります。リストは一般に、たとえば (中略) 等価性をチェックするときに、その値がコンテンツの値から派生したかのように扱われます。多くの人は、当然のことながら、どんなリストでも [1, 2] を使用して同じキーを得ることができると期待する人も多いでしょう。しかし、値による検索は、キーとして使用されるリストが変更されるとすぐに壊れ、同一性による検索では、まったく同じリストを保持する必要があります - これは、他の一般的なリスト操作では必要ありません (少なくとも私が思いつく限りではありません)。

モジュールなどの他のオブジェクトや object などの他のオブジェクトは、オブジェクトのアイデンティティをより大きく扱います (前回、2 つの異なるモジュールオブジェクトに sys と呼ばれる2つの異なるモジュールオブジェクトがあったのはいつだったか)、とにかくそれによって比較されます。したがって、dict キーとして使用される場合、その場合にも ID によって比較されることは、それほど驚くべきことではなく、予想されることでさえあります。