Why is it that I can add normal callables and methods to a set, but not <some list>.append
(for instance)?
For Example:
>>> 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>])
Edit: I noticed that l.append.__hash__()
also gives this error
You cannot add list
s to a set because lists are mutable. Only immutable objects can be added to sets.
l.append
is an instance method. You can think of it as if it were the tuple (l, list.append)
— that is, it's the list.append() method tied to the particular list l
. The list.append() method is immutable but l
is not. So while you can add list.append
to the set you can't add l.append
.
This works:
>>> s.add(list.append)
This does not work:
>>> s.add((l, list.append))
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: unhashable type: 'list'
You're not trying to add list.append
. You're trying to add l.append
which is an instance method, not a class method. list
instances aren't hashable, and apparently their methods aren't hashable either.
Think of it this way. You have 2 lists:
lfoo = []
lbar = []
Now you want to add their respective appends to your set:
s = set()
s.add(lfoo.append)
s.add(lbar.append)
Now when you do the hash lookup for the set, you can't just rely on the function portion of the instance method. Indeed, lfoo
and lbar
ultimately use the same function (list.append
). So that isn't a unique hash. The way you make it unique is by attaching it to an instance. However, the instance doesn't support hashing, so the set has no way of telling the difference between lfoo.append
and lbar.append
.
In Python, list
objects aren't hashable. I suspect that when you hash an instance method, it incorporates the hash of the instance its bound to. As such, you get the TypeError
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With