Python:"可变向量不可哈希"错误

3
我正在使用Python编写的数学软件包SAGE。我试图操作一些向量集,但总是收到上述错误消息。虽然我知道mutable是什么意思,但我完全不知道它告诉我的内容。可以有人用相对简单的概念解释一下我的错误在哪里吗?

2
请展示完整的异常堆栈跟踪和引起异常的代码。 - Pavel Anossov
3个回答

4

我猜您正在寻找类似以下的内容:

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

您可以通过以下方式修复此默认设置。
sage: V.set_immutable(); W.set_immutable()
sage: set([V,W])
set([(3, 4, 5), (1, 2, 3)])

希望这可以帮助您。

3

您只能在set中放置可哈希对象:

集合对象是一个无序的包含不同可哈希对象的集合。

对于Python而言,这意味着对象必须实现一个__hash__方法,以及__eq____cmp__方法。

可变对象没有实现这样的方法,因此不能存储在set中。您可以将不可变序列存储在set中,例如tuplefrozenset

文档中的另一句话:

一个对象如果有一个哈希值,其在生命周期内不会改变(需要一个__hash__()方法),并且可以与其他对象进行比较(需要一个__eq__()__cmp__()方法),则它是可哈希的。相等的可哈希对象必须具有相同的哈希值。
哈希性使对象可用作字典键和集合成员,因为这些数据结构在内部使用哈希值。
Python的所有不可变内置对象都是可哈希的,而没有可变容器(例如列表或字典)是可哈希的。用户定义类的实例默认情况下是可哈希的;它们都不相等,它们的哈希值是它们的id()

谢谢,但对我来说还是太技术化了...下面的答案有点解决了。 - GaryMak

1

这意味着Python无法使用“向量”内容构建集合,因为“向量对象”只是指向其内容的“指针”:内容不是“固定的”,您可以更改它并重新使用相同的向量变量(Python必须重建集合以使其正常工作)。

因此,您只能使用不可变对象(如元组、字符串、数字)的“set”。

例如:

>>> 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'

这是因为您可以更改l1和l2(例如使用.append)。

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

在这种情况下,您不能更改t1和t2的内容。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接