有没有更符合Python习惯的方法来找到列表中距离另一个点最近的点?

11

我有一个2D点的列表,并且想要找到最接近给定点的那个点。下面的代码 (get_closest_point()) 可以实现我想要的功能。但是在Python中有没有更好的方法呢?

class Circle(object):
    def __init__(self, pos):
        self.position = pos


class Point(object):
    ..
    def compute_distance_to(self, p)
        ..

class SomeClient(object):
    ..

    def get_closest_point(self, points, p1):
        closest = (None, float(sys.maxint))
        for p2 in points:
            distance = p2.compute_distance_to(p1) 
            if distance < closest[1]:
                closest = (p2, distance)

        return closest[0]

    def get_closest_circle(self, circles, p1):
        closest = (None, float(sys.maxint))
        for c in circles:
            distance = c.position.compute_distance_to(p1) 
            if distance < closest[1]:
                closest = (c, distance)

        return closest[0]

有趣的问题。一直在反复实现argmax/argmin的某个变体。 - Nicolas78
1个回答

19

你可以使用 min() 函数的 key 参数:

编辑:经过一些考虑,这应该是您的 Point 类的方法,并且我将修复其他明显的缺陷:

class Point(object):
    def get_closest_point(self, points):
        return min(points, key=self.compute_distance_to)

或者,如果需要处理更为复杂的情况,例如一个包含loc属性的实例列表:

min(items, key= lambda item: p1.compute_distance_to(item.loc))

等等,诸如此类


好的回答!为了让它更有趣:如果对象列表不是点,而是具有点成员的对象列表呢?例如,带有中心点的圆形.. - Kristian
@aaronasterling 差一点就成功了:比较操作必须返回对象,而不是距离... 不过还是谢谢你! :) - Kristian
谢谢,伙计们:我替换了我的代码,所有的测试仍然是绿色的! :) - Kristian
1
@Kristian:如果你的键函数只返回距离,请将其包装在一个lambda中,该lambda返回距离和对象:key=lambda p:(self.compute_distance_to(p),p)现在min函数可以正常工作了,您可以得到距离和最近的点。 - PaulMcG
@Paul:key参数用于计算列表中元素的排序权重。min的返回值始终是给定列表的成员之一。 - SingleNegationElimination
@TMG - 你说得对,我被之前的评论误导了,但很容易确认:min(["abc","d","EFLSKDJ"],key=len) 返回的是 "d",而不是 1。 - PaulMcG

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接