为什么 python 的 bisect_left return 是一个有效的索引,即使该值不存在?
Why does python's bisect_left return a valid index even if the value does not exist?
我想查找某个数字是否存在于排序数组中。直截了当,一个数组包含从 1 到 63 的斐波那契数。下面是斐波那契数生成器和它的一些输出。
stacksize = 10000 # default 128 stack
from functools import lru_cache
@lru_cache(stacksize)
def nthfibonacci(n):
if n <= 1:
return 1
elif n == 2:
return 1
elif n > 2:
return nthfibonacci(n - 2) + nthfibonacci(n - 1)
output = [nthfibonacci(k) for k in range(1,63+1)]
# truncated output: [1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610,987,
1597, 2584, 4181, 6765, 10946, 17711, 28657, 46368,.....]
现在我想查找 number 7 是否存在,所以我使用了以下代码
使用 python bisection module
from bisect import bisect_left
elem_index = bisect_left(a=output, x=7, lo=0, hi=len(arr) - 1)
# output of elem_index is 5 ???? . But it is expected to be len(output) +1, right?
# as we know if element is not found it returns len(array) +1
同样,如果我只写一个简单的二进制搜索,它会给我正确的结果如下:
def binsearch(arr, key):
# arr.sort()
low = 0
high = len(arr) - 1
while low <= high:
mid = (low + high) // 2
if arr[mid] == key:
return mid
else:
if arr[mid] < key:
low = mid + 1
else:
high = mid - 1
return -1
print(binsearch(arr, 7)) # it gives me -1 as expected
这是怎么回事?
The documentation on bisect_left
解释行为:
bisect_left(...)
bisect_left(a, x[, lo[, hi]]) -> index
Return the index where to insert item x in list a, assuming a is sorted.
简而言之,bisect_left
(和bisect_right
)告诉您元素存在的位置,如果元素不存在,则告诉您插入的位置。
考虑一个人为的例子。当值存在时,让我们在排序列表中搜索该值。
l = [1, 4, 5]
bisect.bisect_left(l, 4)
# 1
bisect_left
returns 1 因为 l[1]
是 4
。现在,重复该过程,但使用该列表中不存在的值。
bisect.bisect_left(l, 3)
# 1
在这种情况下,l[1]
是您可以在该排序列表中找到 3 如果它存在。
这对您意味着什么?您所要做的就是修改您的函数以查询 bisect_left
、[=24= 返回的索引处的元素]
def binary_search(items, key):
idx = bisect_left(items, key)
if items[idx] != key:
return -1
return idx
如前所述,bisect_left()
just locates the insertion point for an element in a list to maintain sorted order. The documentation also shows 如何将 bisect_*
函数转换为实际查找,因此您可以使用:
def index(lst, elem):
i = bisect_left(lst, elem)
if i != len(lst) and lst[i] == elem:
return i
return -1
我想查找某个数字是否存在于排序数组中。直截了当,一个数组包含从 1 到 63 的斐波那契数。下面是斐波那契数生成器和它的一些输出。
stacksize = 10000 # default 128 stack
from functools import lru_cache
@lru_cache(stacksize)
def nthfibonacci(n):
if n <= 1:
return 1
elif n == 2:
return 1
elif n > 2:
return nthfibonacci(n - 2) + nthfibonacci(n - 1)
output = [nthfibonacci(k) for k in range(1,63+1)]
# truncated output: [1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610,987,
1597, 2584, 4181, 6765, 10946, 17711, 28657, 46368,.....]
现在我想查找 number 7 是否存在,所以我使用了以下代码 使用 python bisection module
from bisect import bisect_left
elem_index = bisect_left(a=output, x=7, lo=0, hi=len(arr) - 1)
# output of elem_index is 5 ???? . But it is expected to be len(output) +1, right?
# as we know if element is not found it returns len(array) +1
同样,如果我只写一个简单的二进制搜索,它会给我正确的结果如下:
def binsearch(arr, key):
# arr.sort()
low = 0
high = len(arr) - 1
while low <= high:
mid = (low + high) // 2
if arr[mid] == key:
return mid
else:
if arr[mid] < key:
low = mid + 1
else:
high = mid - 1
return -1
print(binsearch(arr, 7)) # it gives me -1 as expected
这是怎么回事?
The documentation on bisect_left
解释行为:
bisect_left(...) bisect_left(a, x[, lo[, hi]]) -> index Return the index where to insert item x in list a, assuming a is sorted.
简而言之,bisect_left
(和bisect_right
)告诉您元素存在的位置,如果元素不存在,则告诉您插入的位置。
考虑一个人为的例子。当值存在时,让我们在排序列表中搜索该值。
l = [1, 4, 5]
bisect.bisect_left(l, 4)
# 1
bisect_left
returns 1 因为 l[1]
是 4
。现在,重复该过程,但使用该列表中不存在的值。
bisect.bisect_left(l, 3)
# 1
在这种情况下,l[1]
是您可以在该排序列表中找到 3 如果它存在。
这对您意味着什么?您所要做的就是修改您的函数以查询 bisect_left
、[=24= 返回的索引处的元素]
def binary_search(items, key):
idx = bisect_left(items, key)
if items[idx] != key:
return -1
return idx
如前所述,bisect_left()
just locates the insertion point for an element in a list to maintain sorted order. The documentation also shows 如何将 bisect_*
函数转换为实际查找,因此您可以使用:
def index(lst, elem):
i = bisect_left(lst, elem)
if i != len(lst) and lst[i] == elem:
return i
return -1