根据值的接近程度对两个字典的键进行配对的函数?

function that pairs keys of two dictionaries based on how close their values are?

我想制作一个将两个字典作为输入的函数,其中字典的键是字符串,值是整数或浮点数。 它应该只使用列表理解、for 循环和没有导入的 if 语句。例如,输入应如下所示:

nearest_location({'person_a': 10, 'person_b': 12},{'place_c': 11, 'place_d': 12})

此函数的目标是 return 一个新字典,该字典由字典 1 中的键集和字典 2 中的键集组成,它们根据其对应值的接近程度进行配对。

例如,上面的输入应该return {'person_a': 'place_c', 'person_b': 'place_d'}。这是因为字典 1 中 'person_a', 10 的值最接近 'place_c', 11 的值。对于 'person_b' 和 [=19 的值也是如此=].请注意,新词典中的 整体数量将始终是词典 1 中条目的数量,而不管词典 2 中有多少条目。

接下来对函数中的漏洞和异常进行说明:

例如,

nearest_location({'person_a':10, 'person_b':11, 'person_c':12},{'place_a':10,'place_b':10}) 

应该return

({'person_a':'place_a','person_b':'place_a','person_c':'place_a'])

字典 2 中的所有值都相同,因此字典 2 中 字母顺序 中的第一个键应该与字典 1 中的每个键配对。

我试过的:

代码本身很短而且不是函数,但我想尝试将其作为概念证明。此方法使用 for 循环,但我想在我的函数中使用列表理解。

people = {'person_a': 10, 'person_b': 12}
places = {'place_c': 11, 'place_d': 12}

for i in people:
    for j in places:
        print([i, j], abs(people[i] - places[j]))

这个输出是

['person_a', 'place_c'] 1
['person_a', 'place_d'] 2
['person_b', 'place_c'] 1
['person_b', 'place_d'] 0

如您所见,这不会打印我想要的函数输出字典。然而,它确实计算了字典 1 和 2 中每个键之间的距离。我想用它来以某种方式从中获取最小值 assemble 字典。

def nearest_location(people, places):
    assignments = dict()
    for person, person_location in people.items():
        closest_place, best_distance = '', float('inf')
        for place, place_location in places.items():
            distance = abs(place_location - person_location)
            if distance < best_distance:
                closest_place, best_distance = place, distance
            elif distance == best_distance:
                if place < closest_place:
                    closest_place = place
        assignments[person] = closest_place
    return assignments

nearest_location({'person_a':10, 'person_b':11, 'person_c':12},{'place_a':10,'place_b':10}) 

生成所需的输出

{'person_a': 'place_a', 'person_b': 'place_a', 'person_c': 'place_a'}

无论何时,对于给定的人,存在两个产生相同距离的地方,使用字母顺序较小的那个。

鉴于这个问题,我想说一个简单的解决方案是

def nearest_location(people, places):
    nearest_locations = {}
    for i in people:
        nearest_dist = float("inf")
        nearest_point = None
        for place, location in sorted(places.items()):
            if (abs(people[i]-location)<nearest_dist):
                nearest_dist = abs(people[i]-location)
                nearest_point = place
        nearest_locations[i]=nearest_point
    return nearest_locations

我不完全确定你所说的 “它应该只使用列表推导和 for-loops 而没有导入”是什么意思。因此,如果不允许我们使用“if 语句”,我们可以使用列表推导来做到这一点

def nearest_location(people, places):
    nearest_locations = {}
    for i in people:
        nearest_locations[i]  = sorted([(abs(people[i]-location), place) for place, location in places.items()])[0][1]
    return nearest_locations

def nearest_location(people, places):
    return {i:sorted([(abs(people[i]-location), place) for place, location in places.items()])[0][1] for i in people}