簡體   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