我有一个带有排序号码的列表l,例如
SELECT Description, Color
FROM TableA ta
INNER JOIN TableB tb ON ta.Description LIKE '%' + tb.Color
我试图查找给定数字是否在列表中的两个数字之间。
例如,如果给出了数字12,那么我想获得9和14,因为它们之间有12个。
我用for循环写了这个,
[1, 5, 6, 9, 14, 19]
但是,如果此循环位于另一个循环内并且具有非常大的列表,则这可能很慢。有没有办法在不使用循环的情况下执行此操作?例如,使用numpy因为我知道它对数组的处理能力很强。
答案 0 :(得分:4)
您可以使用np.searchsorted
-
idx = np.searchsorted(l,n)
out = np.take(l,[idx-1,idx])
答案 1 :(得分:2)
您可以使用bisect
本机python模块。
它使用二分法算法在列表中查找插入索引,因此它非常快(log(n)
而不是n)。此外,在流行的平台(Linux,Windows,...)上,它有一个本机实现:无与伦比。
然后报告此索引和下一个索引的值,以说明它们之间的数字。
具有各种输入和输出范围值的小示例。我使用这样的方法来解决背包问题并且非常有效。
# use bisect because the list is known to be sorted
from bisect import bisect
def test(value, l):
idx = bisect(l, value)
# if idx is inside the list, we have a definite find
if 0 < idx < len(l):
return (l[idx-1], l[idx])
# check for boundary condition error
elif len(l) == idx and value == l[-1]:
return (l[-2], l[-1])
else:
return None
def print_formatted_result(value, result):
if result is None:
print (str(value) + " was not found")
else:
print (str(value) + " between " + str(result[0])+ " and " + str(result[1]))
z = [1, 5, 6, 9, 14, 19]
for searched in [0, 1, 9, 12, 19, 50]:
result = test(searched, z)
print_formatted_result(searched, result)
输出:
0 was not found
1 between 1 and 5
9 between 9 and 14
12 between 9 and 14
19 between 14 and 19
50 was not found
请注意,原始代码未找到19,但此代码将其作为特例报告。所有其他情况与原始代码匹配。