GaryMak
GaryMak

Reputation: 133

python: "mutable vectors are unhashable" error

I am using the maths package SAGE, which is written in Python.

I am trying to manipulate some sets of vectors and I keep on getting the above error message. I have absolutely no idea what it is telling me, although I do understand what mutable means Can someone please explain in fairly simple conceptual terms what it is telling me is wrong?

Upvotes: 3

Views: 2175

Answers (3)

kcrisman
kcrisman

Reputation: 4402

I assume you are finding something like

sage: V = vector([1,2,3])
sage: W = vector([3,4,5])
sage: set([V,W])
<snip>
TypeError: mutable vectors are unhashable
sage: 

You can fix this default setting in the following manner.

sage: V.set_immutable(); W.set_immutable()
sage: set([V,W])
set([(3, 4, 5), (1, 2, 3)])

Hope this helps.

Upvotes: 4

Don
Don

Reputation: 17636

It means that Python cannot use the content of 'vectors' to build a set, because the 'vector object' is just a 'pointer' to its content: the content is not 'fixed' and you can change it re-using the same vector vatiable (Python would have to rebuild the set to keep it working).

So, you can use 'set' only of immutable objects (like tuples, strings, numbers).

E.g.

>>> l1 = [1, 2, 3]
>>> l2 = [3, 4, 5]
>>> set([l1, l2])
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unhashable type: 'list'

This is because you can change l1 and l2 (e.g. with .append).

>>> t1 = (1, 2, 3)
>>> t2 = (3, 4, 5)
>>> set([t1, t2])
set([(3, 4, 5), (1, 2, 3)])

In this case you cannot change the content of t1 and t2.

Upvotes: 1

Lev Levitsky
Lev Levitsky

Reputation: 65811

You can only put hashable objects in sets:

A set object is an unordered collection of distinct hashable objects.

For Python, it means that the object must implement a __hash__ method, as well as __eq__ or __cmp__.

Mutable objects do not implement such a method and can't be stored in a set. You can store an immutable sequence is a set, such as a tuple or frozenset.

Another quote from the docs:

An object is hashable if it has a hash value which never changes during its lifetime (it needs a __hash__() method), and can be compared to other objects (it needs an __eq__() or __cmp__() method). Hashable objects which compare equal must have the same hash value.

Hashability makes an object usable as a dictionary key and a set member, because these data structures use the hash value internally.

All of Python’s immutable built-in objects are hashable, while no mutable containers (such as lists or dictionaries) are. Objects which are instances of user-defined classes are hashable by default; they all compare unequal, and their hash value is their id().

Upvotes: 3

Related Questions