You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python欧氏距离计算:closest_point函数结果不符问题求助

问题排查与修改方案

核心错误原因

你的closest_point函数使用字典存储距离-点映射,但字典的键具有唯一性:当多个点到中心点的距离相等时,后遍历到的点会覆盖先遍历到的点。在你的测试案例中:

  • 中心点Point(-30, 9)到Point(-19, 19)的距离平方为:(-30+19)² + (9-19)² = 121 + 100 = 221
  • 到Point(-20, 20)的距离平方同样为:(-30+20)² + (9-20)² = 100 + 121 = 221
    两者距离完全相等,若Point(-20,20)在列表中晚于Point(-19,19)出现,字典会自动覆盖前者,导致返回错误结果。

此外,函数还存在两处冗余问题:

  1. 重复实现了欧几里得距离的计算逻辑,未复用已有的euclidean_distance函数
  2. 找到最小距离后的for循环完全多余,无需遍历字典即可直接返回结果

修改后的代码方案

方案1:保留原有距离计算逻辑,修复字典覆盖问题

直接遍历列表记录当前最近点,避免字典的键冲突问题:

import math

class Point:
    """Defines the Point class for a 2D point.
    Data attributes: 
                    x - the x-coordinate of type float
                    y - the y-coordinate of type float
    """
    
    def __init__(self, x, y):
        """Creates a new Point object"""
        self.x = x
        self.y = y
        
    def __repr__(self):
        """A string representation of this Point"""
        return f"Point({self.x}, {self.y})"
        
def euclidean_distance(point1, point2):
    """returns the euclidean distance between two points"""
    return math.sqrt((point1.x-point2.x) ** 2 + (point1.y-point2.y) **2)

def closest_point(centre, points):
    """returns the nearest point in the list to the centre."""
    if not points:
        return None  # 处理空列表边界情况
    
    # 初始化最近点为列表第一个元素
    min_dist = euclidean_distance(centre, points[0])
    closest = points[0]
    
    for point in points[1:]:
        current_dist = euclidean_distance(centre, point)
        # 仅当当前点距离更近时更新最近点,保留第一个出现的等距点
        if current_dist < min_dist:
            min_dist = current_dist
            closest = point
    return closest

方案2:优化距离计算,使用平方距离提升效率

比较距离大小时,平方距离与实际距离的大小关系完全一致,无需开根号,可避免浮点运算的精度损耗并提升性能:

import math

class Point:
    """Defines the Point class for a 2D point.
    Data attributes: 
                    x - the x-coordinate of type float
                    y - the y-coordinate of type float
    """
    
    def __init__(self, x, y):
        """Creates a new Point object"""
        self.x = x
        self.y = y
        
    def __repr__(self):
        """A string representation of this Point"""
        return f"Point({self.x}, {self.y})"
        
def euclidean_distance(point1, point2):
    """returns the euclidean distance between two points"""
    return math.sqrt((point1.x-point2.x) ** 2 + (point1.y-point2.y) **2)

def squared_distance(point1, point2):
    """returns squared euclidean distance for efficient comparison"""
    return (point1.x - point2.x) ** 2 + (point1.y - point2.y) ** 2

def closest_point(centre, points):
    """returns the nearest point in the list to the centre."""
    if not points:
        return None
    
    min_sq_dist = squared_distance(centre, points[0])
    closest = points[0]
    
    for point in points[1:]:
        current_sq_dist = squared_distance(centre, point)
        if current_sq_dist < min_sq_dist:
            min_sq_dist = current_sq_dist
            closest = point
    return closest

验证说明

修改后的函数会保留第一个出现的最近点,若你的测试列表中Point(-19,19)在Point(-20,20)之前,将返回预期结果。若需要保留最后一个出现的等距点,只需将if current_dist < min_dist改为if current_dist <= min_dist即可。

内容的提问来源于stack exchange,提问作者Nate Lee

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.15 01:05:24