python - 过滤给定条件

时间:2016-04-23 16:33:24

标签: python list lambda

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

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

  2. 假设l中有多个元素,其欧氏距离同时最小。然后我需要从那些元素中返回随机元素。这可以使用列表推导或lambda函数来完成吗?

2 个答案:

答案 0 :(得分:2)

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

>>> 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。

答案 1 :(得分:2)

这是一种使用字典的有效方法:

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()来获取随机点。