I have a simple piece of code which doesn’t run as expected.
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
The matrices are identical, however they both appear seperately when I print the contents of the set. However, if I assign it like below, then the duplicate does not appear.
W = matrix('1, 1, 1, 1; 1, 1, -1, -1; 1, -1, 2, -2; 1, -1, -2, 2')
E = W
Any idea what is happening? I need a way of avoiding duplicate matrices in a program I am writing, which generates a tonne of matrices.
EDIT: I want the following output
set([matrix([[ 1, 1, 1, 1],
[ 1, 1, -1, -1],
[ 1, -1, 2, -2],
[ 1, -1, -2, 2]])])
but instead get the following:
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]])])
You’re running into issues with how python implements checking for similarity between objects internally. Specifically, how objects considered “hashable” are compared.
The way that the python
setconstructor decides if two objects are the same is based on calling a magic method called__hash__(and another called__eq__). Two objects are considered the same if the result of calling__hash__on them returns the same value (and caling__eq__on them returnsTrue). If calling__hash__on the two objects gives different values,setassumes they cannot be considered the same.It is also worth noting that sets can only contain objects that are considered “hashable”, that is, those objects which implement the
__hash__method.Lets see how this works:
Now, lets import numpy, and see what the hash values are for your matrices.
Notice that the hashes are different for
EandWeven though they seem to contain the same thing. Since their hashes are different, they’re going to show up as different objects in the set. When you do assignment likeW = E, then the namesWandEare actually referring to the same object.If you need a workaround for this, you could store the strings you’re using to build the matrices: