我重构,鉴于一系列的如果数字包含在区间隐含定义的时间间隔,检查,然后返回相应的(任何可计算的方式不相关)端点的功能。 就是现在处理工作的代码是:
if p <= 100:
return 0
elif p > 100 and p <= 300:
return 1
elif p > 300 and p <= 500:
return 2
elif p > 500 and p <= 800:
return 3
elif p > 800 and p <= 1000:
return 4
elif p > 1000:
return 5
这是IMO相当可怕的,而在这两个区间缺乏和返回值是硬编码。 任何使用的任何数据结构的当然是可能的。
Answer 1:
import bisect
bisect.bisect_left([100,300,500,800,1000], p)
这里的文档: 平分
Answer 2:
你可以尝试这样的看法:
def check_mapping(p):
mapping = [(100, 0), (300, 1), (500, 2)] # Add all your values and returns here
for check, value in mapping:
if p <= check:
return value
print check_mapping(12)
print check_mapping(101)
print check_mapping(303)
生产:
0
1
2
一如往常,在Python中,会不会有更好的方式来做到这一点。
Answer 3:
这的确是很可怕的。 如果没有要求,没有硬编码,它应该被写成这样:
if p <= 100:
return 0
elif p <= 300:
return 1
elif p <= 500:
return 2
elif p <= 800:
return 3
elif p <= 1000:
return 4
else:
return 5
下面是创建查找函数,线性和使用二进制搜索,与无hardcodings要求满足,和一对夫妇在两个表健全性检查的例子:
def make_linear_lookup(keys, values):
assert sorted(keys) == keys
assert len(values) == len(keys) + 1
def f(query):
return values[sum(1 for key in keys if query > key)]
return f
import bisect
def make_bisect_lookup(keys, values):
assert sorted(keys) == keys
assert len(values) == len(keys) + 1
def f(query):
return values[bisect.bisect_left(keys, query)]
return f
Answer 4:
尝试沿线的东西:
d = {(None,100): 0,
(100,200): 1,
...
(1000, None): 5}
value = 300 # example value
for k,v in d.items():
if (k[0] is None or value > k[0]) and (k[1] is None or value <= k[1]):
return v
Answer 5:
其他方式 ...
def which(lst, p):
return len([1 for el in lst if p > el])
lst = [100, 300, 500, 800, 1000]
which(lst, 2)
which(lst, 101)
which(lst, 1001)
Answer 6:
def which_interval(endpoints, number):
for n, endpoint in enumerate(endpoints):
if number <= endpoint:
return n
previous = endpoint
return n + 1
通过您的端点为列表中的endpoints
,就像这样:
which_interval([100, 300, 500, 800, 1000], 5)
编辑:
以上是线性搜索。 格伦·梅纳德的答案会有更好的表现,因为它采用了二分算法。
文章来源: Python: Mapping from intervals to values