So I'm struggling to find the closest Euclidean distance of two coordinates from data in a dictionary.
First, I have figured out how to compute the distance between two Cartesian coordinates (x,y) using the following:
from math import sqrt
def distance(loc1_coordinates, loc2_coordinates):
point1x, point1y = loc1_coordinates
point2x, point2y = loc2_coordinates
Distance = sqrt((point1x-point2x)**2 (point1y-point2y)**2)
return "The distance between this two points is", str(round(Distance, 14)) " units"
print(distance([0,0],[3,4])) # distance should be 5.0
How to create a new function based on my earlier function so that I get the following as a result?
cities = {'A':[5,21], 'B':[43,76], 'C':[56,19], 'D':[21,37], 'E':[76,23], 'F':[45,56], 'G':[23,13]}
print(closest_destination('A', cities)) # should be 'G'
Update: I am trying to find the smallest distance in the list of calculations of the inputted City: eg: comparing A->B, A->C, A->D, ... and pick the one who has the closest distance
CodePudding user response:
First, change your function to return a numeric value instead of a string (in general you should have functions return values that will let you do other useful things with them in your code, rather than turning them into English-language representations):
from math import sqrt
def distance(loc1_coordinates, loc2_coordinates):
point1x, point1y = loc1_coordinates
point2x, point2y = loc2_coordinates
return sqrt((point1x-point2x)**2 (point1y-point2y)**2)
One of the useful things you can do with this function is to use it as a key
in the min
function to find the minimum distance:
def closest_destination(city: str, cities: dict) -> str:
"""Given a city in a {city: coord} dict, return closest other city."""
other_cities = {k: v for k, v in cities.items() if k != city}
return min(other_cities, key=lambda o: distance(cities[o], cities[city]))
and then:
cities = {'A':[5,21], 'B':[43,76], 'C':[56,19], 'D':[21,37], 'E':[76,23], 'F':[45,56], 'G':[23,13]}
print(closest_destination('A', cities)) # prints 'G'
CodePudding user response:
A single pass approach is to use the key parameter of min
:
def closest_destination(source, locations):
source_location = locations[source]
return min(locations, key=lambda loc: (loc == source, distance(source_location, locations[loc])))
cities = {'A': [5, 21], 'B': [43, 76], 'C': [56, 19], 'D': [21, 37], 'E': [76, 23], 'F': [45, 56], 'G': [23, 13]}
print(closest_destination('A', cities)) # should be 'G'
Output
G
The idea of the function:
lambda loc: (loc == source, distance(source_location, locations[loc]))
to map each city key to a tuple where the first value is 1 if it is equal to the source, therefore it will always come last. Then you break the ties by distance.