在给定条件下过滤最小元素



从元组l列表中,我需要过滤到元组x至少欧几里得距离的元素。

  1. 我可以使用列表理解lambda 函数来执行此操作吗?你可以拿l = [(0,0), (1,1), (2,3), (3,4), (4,5)]x=(3,0).

  2. 假设l中有多个元素同时具有最小欧几里得距离。然后我需要从这些元素中返回随机元素。也可以使用列表理解或 lambda 函数来完成吗?

首先,您应该定义一个函数来获取欧几里得距离。一种方法是将元组转换为复数并获得它们的绝对差异。

>>> dist = lambda t1, t2: abs(complex(*t1) - complex(*t2))

或者,您可以定义自己的函数。这甚至可能更快,因为如果您只想找到具有最小距离的值,则实际上不需要取平方根。然后,可以将该函数用作内置min的键函数。

>>> l = [(0,0), (1,1), (2,3), (3,4), (4,5)]
>>> x = (3,0)
>>> min(l, key = lambda y: dist(y, x))
(1, 1)

如果要获取所有最小值,可以将该值存储在变量中,并使用列表推导式获取距离等于该值的所有值。

>>> m = min(dist(y, x) for y in l)
>>> [y for y in l if dist(x, y) == m]
[(1, 1)]

如果您想要这些随机值,请使用random.choice

>>> random.choice(_)
(1, 1)

但是请注意,此方法将迭代列表两次,并计算每个值的距离两次 - 一次用于查找(任何)最小值,然后再次将每个值与该最小值进行比较。如果性能非常重要,则应使用 @Kasramvd 的 appraoch。

以下是使用字典的有效方法:

from operator import itemgetter
from random import choice
def find_mins(x, lst):
    x1, y1 = x
    result = {}
    for x2, y2 in lst:
        quad_dist = (x1 - x2)**2 + (y1 - y2)**2
        result.setdefault(quad_dist, []).append((x2, y2))
    return choice(min(result.items(), key=itemgetter(0))[1])

演示:

l = [(0,0), (1,1), (2, 2), (2,3), (3,4), (4,5)]
x = (3,0)
find_mins(x, l)
(1, 1)
find_mins(x, l)
(2, 2)
find_mins(x, l)
(2, 2)

此功能将根据坐标与预期点的距离对坐标进行分类,然后根据距离找到最小值并返回相对坐标列表,然后您可以使用random.choice()随机拾取一个点。

最新更新