在字典网格中找到最接近的键

时间:2018-09-18 19:06:24

标签: python dictionary

假设您有一个用字典表示的大网格。在某些坐标处有“玩家”,而其他坐标为空。字典

d = {(500,100): "player1", (480, 230): "player"}

(这些是玩家在网格中的位置)。

现在,如果您的坐标为(500,90),那么两个玩家中哪个最接近?我知道勾股定理必须以某种方式实现才能解决,但是我不知道如何在函数中实现。 这是我走过的最远的地方:

d = {(500,100): "player1", (480, 230): "player"}
def nearest_player(grid, x-cor, y-cor):
'''print out (500,100) as the answer'''

任何想法都将不胜感激。

4 个答案:

答案 0 :(得分:3)

选项1:蛮力

蛮力解决方案可能是搜索所有玩家并选择最接近的玩家:

# I renamed x-cor to x, and y-cor to y since these were not valid python names
def nearest_player(grid, x, y):
    best_distance = float('inf')
    best_player = None

    for pos, player in grid.items():
        # I actually use squared distance since this is 
        # equivalent to the "real" distance
        distance = (pos - x) ** 2 + (pos - y) ** 2

        if distance < best_distance:
            best_distance = distance
            best_player = player

    return best_player

选项2

更优雅的方法如下:

def nearest_player(grid, x, y):
    distances = [(pos - x) ** 2 + (pos - y) ** 2 for pos in grid]
    return grid.values()[distances.index(min(distances))]

我在这里做什么?

首先,您计算所有距离:

distances = [(pos - x) ** 2 + (pos - y) ** 2 for pos in grid]

这将产生一个具有所有距离的数组。 然后计算其最小值的索引:

distances.index(min(distances))

赋予您的grid的值列表会给玩家:

grid.values()[distances.index(min(distances))]

和瞧:)

旁注:进一步走

只是为了大脑使用(我不知道这是否是正确的英语)。 假设您的实际键不是坐标,而是不同的坐标(str,您需要计算Levenshtein distance)。您可以执行以下操作:

def nearest(data, item, d):
    distances = [d(item, i) for i in data]
    return data.values()[distances.index(min(distances))]

,实际上您需要提供一个函数d(用于距离),该函数计算两个项目之间的距离。就是这样。

在您当前的情况下,d为:

def euclidean_distance(x, y):
    return sum((x[i] - y[i]) ** 2 for i in range(0, len(x)))

如果您以xy的形式提供tuplelist

答案 1 :(得分:1)

Using numpy norm:

In[9] newd = {np.linalg.norm(np.array(i)-np.array(c)):v for i, v in d.items()}

In [10]: newd
Out[10]: {10.0: 'player1', 141.4213562373095: 'player'}

In [12]: newd[min(newd)]
Out[12]: 'player1'

答案 2 :(得分:0)

与其他解决方案类似,只是因素有所不同。

import groovy.json.JsonBuilder

def data = [
    Rule: [
        RuleId:0,
        Devices:[1,2,3]
    ]
]
println new JsonBuilder(data).toPrettyString()

我不确定字典是否适合您的目的。列表列表会更自然。

答案 3 :(得分:0)

It turns out you can do argmin in pure Python with min(iterable, key=f), where f is the function to be minimised. So:

d = {(500,100): "player1", (480, 230): "player2"}

target_location = (500, 90)

def square_distance(v1, v2):
    return sum((x1 - x2)**2 for x1, x2 in zip(v1, v2))

nearest_location = min(d, key=lambda location: square_distance(location, target_location))
nearest_player = d[nearest_location]