在字典键列表Python中查找最接近的值

时间:2014-02-18 00:15:28

标签: python list dictionary

有一点:

      a=[X,Y,Z]

我基本上是试图从词典列表中找到距离给定点最近的3个点。

需要比较的数据类型的简化示例以下列形式给出:

       points=[{'Point':1,'co-ordinate':[0,1,2]},{'Point':2',co-ordinate':[0,1,3]},{'Point':3,'co-ordinate':[1,1,2]}] etc.

有任何想法或建议吗?

4 个答案:

答案 0 :(得分:0)

您可以保留反向查找表,返回键值对并将坐标存储为键。这很容易实现。然后,您可以再次返回键,并在每个坐标上执行距离公式。

如您所知,距离公式为:

dist = sqrt((x1 - x2)**2 + (y1 - y2)**2 + (z1 - z2)**2)

注意:您看起来该列表中有3个不同的词典。

答案 1 :(得分:0)

最近意味着你定义了一个距离函数。对于空间中的某个点,norm 2 is usually used。让我们首先编写一个函数来计算两点之间的范数,但是因为我们可能不得不将它用于迭代器(或者因为我预见某些东西,作为一个关键函数),我们将其设为closure(找到最接近的值,很酷)。

from math import sqrt

def norm2(ptA):
    def norm2_close(ptB):
        xA, yA, zA = ptA
        xB, yB, zb = ptB
        return sqrt((xA-xB)**2 + (yA-yB)**2 + (zA-zB)**2)
    return norm2_close

现在,我们可以做到

>>> normFromA = norm2([1, 2, 3])
>>> normFromA([3, 2, 1])
2.8284271247461903
>>> normfromA([4, 5, 6])
5.196152422706632

非常好。但是我们仍然需要从你的dicts列表中获得最小值。有很多可能性,但是当我们编写一个很好的闭包时,让我们修改它以满足我们的需求:

def norm2InDict(ptA):
    def norm2InDict_close(dict_for_ptB):
        xA, yA, zA = ptA
        xB, yB, zB = dict_for_ptB['co-ordinate']
        return sqrt((xA-xB)**2 + (yA-yB)**2 + (zA-zB)**2)
    return norm2InDict_close

让python执行boring work

>>> min(points, key=norm2InDict([1, 2, 3]))
{'co-ordinate': [0, 1, 3], 'Point': 2}

要理解该函数,python将循环遍历列表的元素(每个字典),对它们应用键函数(将计算规范2),比较键并返回具有最小键的元素。对。如果我想要三个最接近的元素,而不是一个元素?好吧,文档告诉我们,我们可以使用heapq模块(我在列表中添加一些点,以获得更多乐趣):

>>> import heapq
>>> points=[
    {'Point':1,'co-ordinate':[0,1,2]},
    {'Point':2,'co-ordinate':[0,1,3]},
    {'Point':3,'co-ordinate':[1,1,2]}, 
    {'Point':4,'co-ordinate':[2,5,2]},
    {'Point':5,'co-ordinate':[1,0,2]},
    {'Point':6,'co-ordinate':[1,2,2]}
]
>>> heapq.nsmallest(3, points, key=norm2InDict([1, 2, 3]))
[{'co-ordinate': [1, 2, 2], 'Point': 6}, {'co-ordinate': [0, 1, 3], 'Point': 2}, {'co-ordinate': [1, 1, 2], 'Point': 3}]

答案 2 :(得分:0)

您可以根据距离函数对点列表进行排序,然后使用第一个点。

import math
a=[0,0,0]

def dist(p0,p1):
    return math.sqrt((p1[0]-p0[0])**2+(p1[1]-p0[1])**2+(p1[2]-p0[2])**2)

points=[{'Point':1,'co-ordinate':[0,1,2]},{'Point':2,'co-ordinate':[0,1,3]},{'Point':3,'co-ordinate':[1,1,2]},] 

sorted_by_dist = sorted(points,key=lambda p:dist(a,p['co-ordinate']))
closest = sorted_by_dist[0]
furthest = sorted_by_dist[-1]

答案 3 :(得分:0)

在此处了解sorted功能==> https://wiki.python.org/moin/HowTo/Sorting。我认为要查找的是key函数中的sorted选项。

一旦你知道了排序的函数,你可以只对字典进行排序,然后键入,只需提供函数来对其进行排序。因此,我们假设您将p作为

p = [2,3,4] # or any other list value ...

然后,一个接受这一点和另一个并返回一个小说的函数可以写成:

# Note that there s no need for the Numpy dependency. I do this only for 
# brevety. You can use the dist function which was previously mentioned.
import numpy as np
def dist(p1, p2): 
    p1, p2 = np.array(p1), np.array(p2)
    return sqrt(sum((p1 - p2)**2))

现在你可以对数组进行排序,并将前3个点作为:

pointList = sorted(points, key = lambda x: dist(x['co-ordinate'], p)  )[:3]