让我们说我有一个Python字典,其中的键实际上是整数。我可以这样创建一个:
>>> d = dict([(1, 0), (7, 10), (28, 20)])
>>> d
{1: 0, 7: 10, 28: 20}
现在,我想进行查找,如果找到了密钥,则返回其索引。这部分真的很容易,就像这样:
>>> key = 7
>>> d[key]
10
如果未找到密钥,那么我想返回密钥的绑定。例如:
>>> key = 6
>>> d[key]
Bound(1, 7)
由于6不作为键存在,因此我返回了它们之间的2个键。 是否可以在基本上不迭代整个字典的情况下完成此事?如果没有,那么实际上不需要回答这个问题。如果确实可行,请尽可能包含一些性能影响。谢谢。
答案 0 :(得分:5)
这是一个使用函数访问普通字典的解决方案(我使用了OrderedDict
,因为我现在使用的是Python的较旧版本,如果您使用的是Python 3.6,则可以使用普通的dict
或更多(按订单订购)。
我们按键对字典进行排序,这使我们可以使用bisect快速找到周围的键。
import bisect
from collections import OrderedDict
d = OrderedDict(sorted([(1, 0), (7, 10), (28, 20)])) # Could be a simple dict with Python 3.6+
class Bound:
def __init__(self, a, b):
self.a = a
self.b = b
def __repr__(self):
return 'Bound({}, {})'.format(self.a, self.b)
def closest(key, d):
try:
return d[key]
except KeyError:
keys = list(d.keys())
ins_point = bisect.bisect(keys, key)
return Bound(keys[ins_point-1] if ins_point >= 1 else None,
keys[ins_point] if ins_point < len(keys) else None)
closest(7, d)
# 10
closest(8, d)
# Bound(7, 28)
closest(30, d)
# Bound(28, None)
closest(-1, d)
# Bound(None, 1)
您还可以继承dict
的子类,更新__missing__
方法(假定dict
是有序的,则Python> = 3.6的代码:
import bisect
class Bound:
def __init__(self, a, b):
self.a = a
self.b = b
def __repr__(self):
return 'Bound({}, {})'.format(self.a, self.b)
class BoundDict(dict):
def __missing__(self, key):
keys = list(self.keys())
ins_point = bisect.bisect(keys, key)
return Bound(keys[ins_point-1] if ins_point >= 1 else None,
keys[ins_point] if ins_point < len(keys) else None)
d = BoundDict(sorted([(1, 0), (7, 10), (28, 20)]))
print(d[7])
# 10
print(d[8])
# Bound(7, 28)
print(d[30])
# Bound(28, None)
print(d[-1])
# Bound(None, 1)
答案 1 :(得分:2)
使用自定义字典类的解决方案:
runId = sys.argv[1]
trth = TrThDownload(runId)
data = trth.data
concurrences = min(len(data),10)
p = pool.ThreadPool(concurrences)
p.map(trth.runDownloader, data)
p.terminate()
p.close()
p.join()
答案 2 :(得分:0)
def bound(x, d):
if x in d:
return x
else:
for i in sorted(d):
if x > i:
l = i
for j in sorted(d, reverse=True):
if j > x:
h = j
return(l,h)
d = dict([(1, 0), (7, 10), (28, 20), (4,5), (2,5), (15,10)])
bound(17,d)
(15,28)