3

From a list of tuple l, I need to filter the element which is at least euclidean distance from tuple x.

  1. Can I do this using list comprehension or lambda function? You can take l = [(0,0), (1,1), (2,3), (3,4), (4,5)] and x=(3,0).

  2. Suppose there are more than one elements in l whose euclidean distance is minimum at same time. Then I need to return random elements from those elements. Can this be done using list comprehension or lambda function too?

2
  • 1) Yes. 2) Yes. Did you try it? Commented Apr 23, 2016 at 16:40
  • @DisplayName I have no idea how to do this in one line. For 3 lines of code, yes I have. Commented Apr 23, 2016 at 16:42

2 Answers 2

3

First you should define a function to get the Euclidian distance. One way would be to just convert the tuples to complex numbers and get their absolute difference.

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

Alternatively, you could define your own function. That might even be faster, since you do not really need to take the square root if you just want to find the value that has the minimum distance. You can then use that function as a key function to the min builtin.

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

If you want to get all the minimum values, you could store that value in a variable and use a list comprehension to get all values whose distance is equal to that value.

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

If you want a random value of those, use random.choice:

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

Note, however, that this approach will iterate the list twice, and also calculate the distance of each value twice -- once to find the (any) minimum value, and then again to compare each value to that minimum. If performance is very important, you should use @Kasramvd's appraoch.

Sign up to request clarification or add additional context in comments.

2 Comments

I was just trying to golf around. Performance is not my concern at the moment since my dataset is small.
Since python3.8 you can do from math import dist: docs.python.org/3/library/math.html#math.dist
2

Here is an efficient approach using dictionary:

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])

Demo :

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)

This function will categorize your coordinates based on their distance from intended point then find the minimum based on the distance and return the list of relative coordinates, then you can use random.choice() to pick up a random point.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.