Как я могу использовать встроенную функцию, чтобы найти ближайшее значение в списке к цели?

#python

#python

Вопрос:

Например, учитывая

 from collections import namedtuple
Point = namedtuple('Point', ['x', 'y'])
points = [Point(x=1.0, y=1.0), Point(x=2.0, y=2.0), Point(x=5.0, y=5.0)] 
target = Point(x=4.5, y=5.0)
closest_point = find_closest(target, points)
  

Я хочу вернуть Point(x=5.0, y=5.0) . В идеале я хотел бы использовать встроенную функцию, которая принимает, (list, target, comp) где comp принимает (a, b) -> float , и цель состоит в том, чтобы найти такое a из list , которое сводит к минимуму (a, target) , например:

 closest_point = find_closest(points, target, dist) # where dist is (a.x-b.x)**2   (a.y-b.y)**2
  

Причина, по которой я заинтересован в этом, заключается в том, что я обнаружил, что пишу 3 дублирующиеся функции, где единственное отличие заключается в том, что dist функции (и они используют разные поля для их вычисления).

Комментарии:

1. Используйте min() с пользовательским ключом.

2. @meowgoesthedog не могли бы вы дать мне указатель на код?

3. Сначала попробуйте сами и вернитесь, если вы все еще застряли.

4. bisect.bisect может помочь с этим

Ответ №1:

min Функция может принимать key аргумент, который является функцией для использования в качестве вашего компаратора. В этом случае вы можете написать lambda для вычисления расстояния от каждой точки до target .

 >>> min(points, key=lambda pt : sqrt((target.x - pt.x)**2   (target.y - pt.y)**2))
Point(x=5.0, y=5.0)
  

Комментарии:

1. Небольшая оптимизация: sqrt не требуется.

2. Просто обратите внимание, что здесь вам не нужно вычисление sqrt. наименьший sqrt также будет наименьшим квадратом.

Ответ №2:

Вы можете попробовать следующий пример кода:

 def find_closest(target, points):
    dist = []
    for i in points:
        dist.append((i.x - target.x)**2   (i.y - target.y)**2)
    min_index = dist.index(min(dist))      
    return points[min_index]


closest_point = find_closest(target, points)
  

Это выдает вывод: Point(x=5.0, y=5.0)