7

通常の呼び出し可能オブジェクトとメソッドをセットに追加できるのに、<some list>.append(たとえば)できないのはなぜですか?

例えば:

>>> l = []
>>> s = set()
>>> s.add(l.append)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unhashable type: 'list'
>>> type(l.append)
<type 'builtin_function_or_method'>
>>> type(map)
<type 'builtin_function_or_method'>
>>> s.add(map)
>>> def func(): print 'func'
... 
>>> s.add(func)
>>> print s
set([<built-in function map>, <function func at 0x10a659758>])

l.append.__hash__()編集:私はそれもこのエラーを与えることに気づきました

4

3 に答える 3

8

listリストは変更可能であるため、セットにsを追加することはできません。セットに追加できるのは不変オブジェクトのみです。

l.appendインスタンスメソッドです。タプルであるかのように考えることができます。(l, list.append)つまり、特定のリストに関連付けられたlist.append()メソッドlです。list.append()メソッドは不変ですが、lそうではありません。したがってlist.append、セットに追加することはできますが、追加することはできませんl.append

これは機能します:

>>> s.add(list.append)

これは動作しません:

>>> s.add((l, list.append))
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unhashable type: 'list'
于 2012-11-28T01:48:31.010 に答える
3

追加しようとしているのではありませんlist.appendl.appendクラスメソッドではなく、インスタンスメソッド を追加しようとしています。listインスタンスはハッシュ可能ではなく、明らかにそれらのメソッドもハッシュ可能ではありません。

このように考えてください。2つのリストがあります:

lfoo = []
lbar = []

次に、それぞれの追加をセットに追加します。

s = set()
s.add(lfoo.append)
s.add(lbar.append)

これで、セットのハッシュルックアップを実行するときに、インスタンスメソッドの関数部分だけに依存することはできません。確かに、lfooそしてlbar最終的には同じ関数を使用します(list.append)。したがって、これは一意のハッシュではありません。ユニークにする方法は、インスタンスにアタッチすることです。ただし、インスタンスはハッシュをサポートしていないため、セットにはとの違いを区別する方法がありませlfoo.appendlbar.append

于 2012-11-28T01:45:48.953 に答える
2

Pythonでは、listオブジェクトはハッシュ可能ではありません。インスタンスメソッドをハッシュすると、バインド先のインスタンスのハッシュが組み込まれると思います。このように、あなたはを取得しTypeErrorます。

于 2012-11-28T01:46:55.273 に答える