【问题标题】:Set subtraction in Python在 Python 中设置减法
【发布时间】:2015-10-06 01:37:57
【问题描述】:

在我的 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) + ')' 

还有两个列表,initialPointsListburnedPointsList

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

我想计算initialPointsListburnedPointsList之间的差异

我已经执行了:

result = set(initialPointsList) - set(burnedPointsList)
for item in result:
    print item

并得到以下输出:

point: (1, 1)
point: (1, 4)
point: (1, 5)
point: (1, 6)
point: (1, 2)
point: (1, 3)
point: (1, 7)

但我期待另一个结果,没有烧点坐标:

point: (1, 1)
point: (1, 4)
point: (1, 5)
point: (1, 6)
point: (1, 7)

在 Python 中最好的方法是什么?我的代码有什么问题?

【问题讨论】:

    标签: python python-2.7


    【解决方案1】:

    如果你想让它正常工作,你需要定义__eq__()__hash__() 特殊方法。如果您定义了__eq__(),那么定义__ne__() 通常也是一个好主意。

    __eq__() 应该返回 True 如果它的参数是等价的(它们的 x 和 y 值相同)。 __ne__() 应该相反。 __eq__() 通常也需要进行类型检查,如果“其他”值与 self 的类型不同,则返回 false。

    __hash__() 应该返回一个数字。对于与__eq__() 比较相等的两个值,该数字应该相同,并且对于不同的值,它是可取的,但不是严格要求的。一个好的实现是这样的:

    def __hash__(self):
        return hash((self.x, self.y))
    

    元组散列算法将以统计良好的方式组合其元素的散列值。您有时可能会看到人们在这里推荐按位异或(即self.x ^ self.y),但这不是一个好主意。该技术会丢弃它们共有的所有位,这会导致散列性能下降(例如,如果self.x == self.y,它总是返回零)。

    最后,您需要确保在构造对象后散列值不会改变。这可以通过将self.xself.y 转换为只读properties 来轻松实现。

    【讨论】:

    【解决方案2】:

    为了完整起见,这里将是 Kevin 的回答中提到的 __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))
    

    我通过将这些方法添加到您的类来对其进行测试,它会产生预期的输出:

    point: (1, 5)
    point: (1, 6)
    point: (1, 1)
    point: (1, 4)
    point: (1, 7)
    

    【讨论】:

    • 你不想只测试other。我建议测试type(self) is type(other),因为我们只想返回完全相同类型的对象的相等性(否则,您可以使用self == other and not other == self)。注意type(None) 是合法的并且返回一个合理的唯一值。
    • 谢谢凯文,我更新了我的答案。另外,这只是一个很好的技术,我可能需要更新一些我自己的代码。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-06-18
    • 2011-07-02
    • 1970-01-01
    • 2019-04-16
    • 2016-03-13
    • 2021-10-10
    相关资源
    最近更新 更多