【问题标题】:Python Set Intersection on Object AttributesPython 设置对象属性的交集
【发布时间】:2020-03-31 18:11:39
【问题描述】:

我有 2 个集合,每个集合包含以下类的对象:

class pointInfo:
    x = 0
    y = 0
    steps = 0

我想找到这两组的交集,但只在 x 和 y 值上。 类似:

def findIntersections(pointInfoSet1, pointInfoSetwire2):
    return [pointInfo for pointInfo in pointInfoSet1 if pointInfo.x, pointInfo.y in pointInfoSet2]

我知道如果你在 python 中有 2 个集合,你可以只做 set1.intersection(set2),但在这种情况下这不起作用,因为我只想找到对象属性的某个子集是相同的,而不是相同的对象。提前致谢!

【问题讨论】:

  • pointInfo 对象在其xy 上是否更普遍?您可以编写 __eq____hash__ 方法来反映这一点,然后设置交集将正常工作。
  • 是的,基本上我有 2 条线,它们是一组点,我试图找到与 0,0 的距离最小的交点,同时遵循电线路线。所以 x 和 y 坐标有大约 30 个交点,但步数永远不相等。所以我只是想根据 x 和 y 值进行比较

标签: python set


【解决方案1】:

这是一个解决方案,它使 Point 对象的 x 和 y 属性为 Hashable

class Point:
    def __init__(self, x=0, y=0, step=0):
        self.x = x
        self.y = y
        self.step = step
    def __eq__(self, other):
        if not isinstance(other, Point):
            return NotImplemented
        return (self.x, self.y) == (other.x, other.y)
    def __hash__(self):
        return hash((self.x, self.y))
    def __repr__(self):
        return "Point(x={0.x}, y={0.y}, step={0.step})".format(self)

然后我们可以将它们放在集合中并自然地得到交叉点:

{Point(1, 1, 1), Point(2, 2)} & {Point(1, 1, 2)}
# {Point(x=1, y=1, step=2)}

假设没有电线交叉,更好的解决方案可能是遍历两条电线,维护一个点到步骤的字典,并在每个交叉点输出步骤的总和:

from itertools import chain

def stepsToIntersections(wire1, wire2):
    seen = {}
    for point in chain(wire1, wire2):
        if point in seen:
            yield point.step + seen[point]
        else:
            seen[point] = point.step

closest = min(stepsToIntersections(wire1, wire2))

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-04-12
    • 1970-01-01
    • 2014-11-13
    • 2012-06-24
    • 1970-01-01
    • 2011-08-17
    • 2016-02-25
    • 1970-01-01
    相关资源
    最近更新 更多