我有一串带整数键的字典。对于我没有的按键,我希望能够在它想要检索的键之前和之后检索最小和最大的键,但这不存在。
java中的Treemap类有两个完全相同的方法:ceilingkey()
和floorkey()
。
如何使用python执行此操作?
作为一个例子,我有一个这样的字典:
{ 1: "1", 4: "4", 6: "6" ..., 100: "100" }
如果我要求输入密钥1
,我会检索"1"
,
但是,如果我查找密钥3
,我应该KeyError
,因此可以获得floor(3) = 1
和ceil(3) = 4
。
答案 0 :(得分:5)
def floor_key(d, key):
if key in d:
return key
return max(k for k in d if k < key)
def ceil_key(d, key):
if key in d:
return key
return min(k for k in d if k > key)
我不确定你想如何处理边境条件。请注意,如果要求键的下限/上限低于/高于dict中的任何内容,则会引发异常(ValueError
)。
答案 1 :(得分:2)
您可以在此处使用bisect模块,以防未找到密钥,然后它可以在O(log N)
时间内找到ceil和floor值。:
>>> import bisect
>>> from random import randint
def get_value(dic, key):
if key in dic:
return dic[key]
else:
ind = bisect.bisect(keys, key)
d = {}
if ind > 0:
d["floor"] = dic[keys[ind-1]]
if ind < len(keys):
d["ceil"] = dic[keys[ind]]
return d
...
>>> dic = {randint(0,100) : x for x in xrange(10)}
>>> dic
{65: 6, 4: 5, 1: 7, 40: 8, 10: 4, 50: 0, 68: 2, 27: 9, 61: 3}
为bisect
创建排序的键列表:
>>> keys = sorted(dic)
>>> keys
[1, 4, 10, 27, 40, 50, 61, 65, 68]
现在使用功能:
>>> get_value(dic, 4)
5
对3
而言,ceil和floor都是可用的:
>>> get_value(dic, 3)
{'ceil': 5, 'floor': 7}
0
小于最小键,因此仅返回ceil
:
>>> get_value(dic, 0)
{'ceil': 7}
对于大于最大键的键,将仅返回floor
值:
>>> get_value(dic, 70)
{'floor': 2}
答案 2 :(得分:2)
这是一个有趣的使用bisect。
import bisect
def ceiling_key(d, key):
keys = sorted(d.keys())
idx = bisect.bisect_left(keys, key)
if key in d:
idx += 1
return keys[idx]
def floor_key(d, key):
keys = sorted(d.keys())
idx = bisect.bisect_left(keys, key) - 1
return keys[idx]
...
>>> ceiling_key(d, 1)
4
>>> ceiling_key(d, 2)
4
>>> ceiling_key(d, 4)
6
>>> ceiling_key(d, 3)
4
>>> ceiling_key(d, 2)
4
>>> ceiling_key(d, 1)
4
>>> ceiling_key(d, 0)
1
>>> ceiling_key(d, 6)
100
>>> floor_key(d, 6)
4
>>> floor_key(d, 7)
6
>>> floor_key(d, 101)
100
>>> floor_key(d, 100)
6