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