如果我有这样的字典
>>> d = {10: 3, 100: 2, 1000: 1}
我可以输入类似的内容:
>>> d.get(10), d.get(100), d.get(1000)
(3, 2, 1)
虽然我想要,如果找不到给定的密钥,则返回与最近的密钥对应的给定密钥的值:
>>> d.get(20), d.get(60), d.get(200)
(3, 2, 2)
相反,Python中的结果是
(None, None, None)
实现我描述的行为的Pythonic方法是什么?
由于
答案 0 :(得分:17)
您可以从dict
派生以更改get()
方法的行为:
class ClosestDict(dict):
def get(self, key):
key = min(self.iterkeys(), key=lambda x: abs(x - key))
return dict.get(self, key)
d = ClosestDict({10: 3, 100: 2, 1000: 1})
print (d.get(20), d.get(60), d.get(200))
打印
(3, 2, 2)
请注意get()
的复杂性不再是O(1),而是O(n)。
答案 1 :(得分:6)
bisect模块允许快速查找排序列表中的插入位置。
from bisect import bisect_right
def closest_matches(data, query):
keys = sorted(data)
return [data[i] for i in (min(map(abs, (keys[p-1], keys[p]))) for p in (bisect_right(keys, k) for k in query))]
>>> d = {10: 3, 100: 2, 1000: 1}
>>> closest_matches(d, [20, 60, 200])
[3, 3, 2]
答案 2 :(得分:2)