繁体   English   中英

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

[英]Python: Elegant way of determining the nearest match for numbers in a dictionary

我有一个字典结构,可将id(整数)映射为数字(双精度)。 数字实际上是一件物品的重量。

我正在编写一个函数,该函数将允许我获取给定权重的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

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

我想不起来,我想一种更pythonic /优雅的方法是做类似将自定义函数传递给min函数的事情-不知道这是否可行...

[[更新]]

我正在运行Python 2.6.5

尝试按重量与目标值的距离对物品进行排序:

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:

distances = ((k, abs(v - value)) for k, v in bucketed_items_dict.items())
return min(distances, key=lambda x:x[1])[0]
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]

或简而言之:

def getBucketIdByValue(bucket, value):
    return min((abs(number-value),id) for id,number in bucket.items())[1]

此函数使用存储桶创建ID /数字对,然后创建距离/ ID对的迭代器,然后获取它的第一个最小对,最后提取该对的ID并返回它。

距离定义为数字与所需值之差的绝对值。

最小值定义为距离最小的线对。 如果还有更多,则返回ID最低的货币对。

您可以使用bisect在排序键中找到最接近权重的索引:

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

这样,您只需要检查2个权重并找到最佳权重即可。 排序和二进制搜索可能比计算所有权重并找到最佳权重要快。

我还将考虑bisect模块。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM