[英]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.