我有一段不按预期运行的简单代码。

from numpy import *
from numpy.linalg import *
from sets import Set

W = matrix('1, 1, 1, 1; 1, 1, -1, -1; 1, -1, 2, -2; 1, -1, -2, 2')
E = matrix('1, 1, 1, 1; 1, 1, -1, -1; 1, -1, 2, -2; 1, -1, -2, 2')

matrices = Set([])
matrices.add(W)
matrices.add(E)
matrices

矩阵是相同的,但是当我打印集合的内容时,它们都分开显示。但是,如果我像下面这样分配,则不会出现重复项。
W = matrix('1, 1, 1, 1; 1, 1, -1, -1; 1, -1, 2, -2; 1, -1, -2, 2')
E = W

知道发生了什么吗我需要一种避免在我编写的程序中重复矩阵的方法,该程序生成大量矩阵。
编辑:我想要以下输出
set([matrix([[ 1,  1,  1,  1],
        [ 1,  1, -1, -1],
        [ 1, -1,  2, -2],
        [ 1, -1, -2,  2]])])

但是,你可以得到以下信息:
set([matrix([[ 1,  1,  1,  1],
        [ 1,  1, -1, -1],
        [ 1, -1,  2, -2],
        [ 1, -1, -2,  2]]), matrix([[ 1,  1,  1,  1],
        [ 1,  1, -1, -1],
        [ 1, -1,  2, -2],
        [ 1, -1, -2,  2]])])

最佳答案

python如何在内部实现检查对象之间的相似性,您遇到了一些问题具体来说,如何比较被视为“散列”的对象。
pythonset构造函数决定两个对象是否相同的方法是基于调用一个名为__hash__的神奇方法(以及另一个名为__eq__的方法)。如果对两个对象调用__hash__的结果返回相同的值(而对它们进行caling__eq__则返回True,则认为这两个对象是相同的。如果对两个对象调用__hash__会给出不同的值,set假设不能将它们视为相同的值。
值得注意的是,集合只能包含被认为是“可散列”的对象,即那些实现__hash__方法的对象。
让我们看看这是如何工作的:

In [73]: a = "one"
In [74]: b = "one"
In [75]: c = "two"

In [76]: a.__hash__()
Out[76]: -261223665

In [77]: b.__hash__()
Out[77]: -261223665

In [78]: c.__hash__()
Out[78]: 323309869

In [79]: set([a,b,c])
Out[79]: set(['two', 'one'])

现在,让我们导入numpy,看看矩阵的散列值是什么。
In [81]: import numpy as np
In [82]: W = np.matrix('1, 1, 1, 1; 1, 1, -1, -1; 1, -1, 2, -2; 1, -1, -2, 2')
In [83]: E = np.matrix('1, 1, 1, 1; 1, 1, -1, -1; 1, -1, 2, -2; 1, -1, -2, 2')

In [84]: W.__hash__()
Out[84]: 4879307

In [85]: E.__hash__()
Out[85]: 4879135

注意EW的散列是不同的,尽管它们似乎包含相同的内容因为它们的散列是不同的,所以它们将在集合中显示为不同的对象当您执行类似于W = E的赋值时,名称WE实际上是指同一个对象。
如果需要解决方法,可以存储用于生成矩阵的字符串:
In [86]: set(['1, 1, 1, 1; 1, 1, -1, -1; 1, -1, 2, -2; 1, -1, -2, 2',
              '1, 1, 1, 1; 1, 1, -1, -1; 1, -1, 2, -2; 1, -1, -2, 2'])
Out[86]: set(['1, 1, 1, 1; 1, 1, -1, -1; 1, -1, 2, -2; 1, -1, -2, 2'])

08-26 20:25
查看更多