[英]Set subtraction in Python
In my Python code I have this class: 在我的Python代码中,我有这个类:
class _Point2D:
def __init__(self, x, y):
self.x = x
self.y = y
def __repr__(self):
return 'point: (' + str(self.x) + ', ' + str(self.y) + ')'
And there are two lists, initialPointsList
and burnedPointsList
: 并且有两个列表,
initialPointsList
和burnedPointsList
:
initialPointsList = []
initialPointsList.append(_Point2D(1, 1))
initialPointsList.append(_Point2D(1, 2))
initialPointsList.append(_Point2D(1, 3))
initialPointsList.append(_Point2D(1, 4))
initialPointsList.append(_Point2D(1, 5))
initialPointsList.append(_Point2D(1, 6))
initialPointsList.append(_Point2D(1, 7))
burnedPointsList = []
burnedPointsList.append(_Point2D(1, 2))
burnedPointsList.append(_Point2D(1, 3))
I want to calculate the difference between initialPointsList
and burnedPointsList
我想计算
initialPointsList
和burnedPointsList
之间的区别
I have executed: 我执行了:
result = set(initialPointsList) - set(burnedPointsList)
for item in result:
print item
And get the following output: 并获得以下输出:
point: (1, 1)
point: (1, 4)
point: (1, 5)
point: (1, 6)
point: (1, 2)
point: (1, 3)
point: (1, 7)
But I expected another result, without burned point coordinates: 但我期待另一个结果,没有烧伤点坐标:
point: (1, 1)
point: (1, 4)
point: (1, 5)
point: (1, 6)
point: (1, 7)
What is the best way to do that in Python? 在Python中最好的方法是什么? What is incorrect with my code ?
我的代码有什么不对?
If you want this to work correctly, you need to define the __eq__()
and __hash__()
special methods. 如果要使其正常工作,则需要定义
__eq__()
和__hash__()
特殊方法。 If you define __eq__()
, it's usually also a good idea to define __ne__()
. 如果定义
__eq__()
,定义__ne__()
通常也是个好主意。
__eq__()
should return True
if its arguments are equivalent (their x and y values are the same). __eq__()
的参数是等价的(它们的x和y值相同),则它们应该返回True
。 __ne__()
should do the opposite. __ne__()
应该反其道而行之。 It's usually also desirable for __eq__()
to do type checking, and return false if the "other" value is not of the same type as self
. 通常,
__eq__()
通常也需要进行类型检查,如果“其他”值与self
类型不同,则返回false。
__hash__()
should return a number. __hash__()
应该返回一个数字。 The number should be the same for two values which compare equal with __eq__()
, and it's desirable but not strictly required for it to be different for distinct values. 对于与
__eq__()
相比较的两个值,该数字应该相同,并且它是可取的但不是严格要求它对于不同的值是不同的。 A good implementation is this: 一个很好的实现是这样的:
def __hash__(self):
return hash((self.x, self.y))
The tuple hashing algorithm will combine the hash values of its elements in a statistically well-behaved way. 元组散列算法将以统计上良好的方式组合其元素的散列值。 You may sometimes see people recommend bitwise XOR (ie
self.x ^ self.y
) here, but that isn't a good idea. 你有时可能会在这里看到人们推荐按位异或(即
self.x ^ self.y
),但这不是一个好主意。 That technique throws away all the bits they have in common, which makes for inferior hashing performance (eg it always returns zero if self.x == self.y
). 该技术抛弃了它们共有的所有位,这使得散列性能较差(例如,如果
self.x == self.y
它总是返回零)。
Finally, you need to make sure that hash values don't change after an object has been constructed . 最后,您需要确保在构造对象后哈希值不会更改 。 This is most easily accomplished by converting
self.x
and self.y
into read-only properties . 通过将
self.x
和self.y
转换为只读属性,可以轻松完成此操作。
For completeness, here would be the __eq__
, __ne__
, and __hash__
methods as mentioned in Kevin's answer. 为了完整起见,这里将是
__eq__
, __ne__
和__hash__
在凯文的答复中提到的方法。
def __eq__(self, other):
return type(self) is type(other) and self.x == other.x and self.y == other.y
def __ne__(self, other):
return not self.__eq__(other)
def __hash__(self):
return hash((self.x, self.y))
I test it by adding these methods to your class and it produces the expected output: 我通过将这些方法添加到您的类来测试它,它产生预期的输出:
point: (1, 5)
point: (1, 6)
point: (1, 1)
point: (1, 4)
point: (1, 7)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.