Python:确定字典中数字最接近匹配的优雅方法

2024-09-26 22:54:35 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个字典结构,它将一个id(整数)映射成一个数字(double)。数字实际上是物品的重量。在

我正在编写一个函数,它允许我获取给定权重的id(如果权重在dict中找到,否则,它将返回下一个最近的(即最近匹配的)权重的id。在

到目前为止,我得到的是:

def getBucketIdByValue(bucketed_items_dict, value):
    sorted_keys = sorted(bucketed_items_dict.keys())
    threshold = abs(bucketed_items_dict[sorted_keys[-2]] -bucketed_items_dict[sorted_keys[-1]]) # determine gap size between numbers

    # create a small dict containing likely candidates
    temp = dict([(x - value),x] for x in bucketed_items_dict.values() if abs(x - value) <= threshold)
    print 'DEBUG: Deviations list: ', temp.keys()
    smallest_deviation = min(temp.keys()) if value >= 0 else max(temp.keys()) # Not sure about this ?
    smallest_deviation_key = temp[smallest_deviation]
    print 'DEBUG: found bucketed item key:',smallest_deviation_key
    return smallest_deviation_key

我不确定逻辑是否正确(尤其是在我得到最小偏差的地方)。无论如何,即使逻辑是正确的,这似乎是一种过于复杂的做事方式。有没有更优雅的/Python式的方法?在

在我的脑海中,我认为一个更为python/优雅的方法是做一些事情,比如将一个自定义函数传递给min函数-不知道这是否可能。。。在

[[更新]]

我运行的是python2.6.5


Tags: key函数idthresholdvalueitems数字keys
3条回答
def getBucketIdByValue(bucket, value):
    distances = [( id , abs( number - value ) ) for id , number in bucket.items()]
    swapped = [( distance , id ) for id , distance in distances]
    minimum = min ( swapped )
    return minimum[1]

或者简而言之:

^{pr2}$

这个函数使用bucket创建id/number对,然后创建distance/id对的迭代器,然后获取它的第一个最小值对,最后提取该对的id并返回它。在

距离被定义为数值与所求值之差的绝对值。在

最小值定义为距离最小的一对。如果有更多,则返回id最低的对。在

可以使用排序键中的对分查找最近权重的索引:

import bisect

def bisect_weight(sorted_keys, value):
    index = bisect.bisect(sorted_keys, value)
    # edge cases
    if index == 0: return sorted_keys[0]
    if index == len(sorted_keys): return sorted_keys[index - 1]
    minor_weight = sorted_keys[index - 1]
    greater_weight = sorted_keys[index]

    return minor_weight if abs(minor_weight - value) < abs(greater_weight - value) else greater_weight

这样你只需要检查两个砝码,找到最好的一个。排序和二进制搜索可能比计算所有权重更快,并找到最佳权重。在

尝试按重量与目标值之间的距离对项目进行排序:

from operator import itemgetter
distances = ((k, abs(v - value)) for k, v in bucketed_items_dict.items())
return min(distances, key=itemgetter(1))[0]

或者使用lambda函数而不是itemgetter:

^{pr2}$

相关问题 更多 >

    热门问题