Python二进制搜索始终返回目标未找到的值

时间:2010-09-11 05:16:18

标签: python search binary-search

我编写了以下代码,在列表或元组target中对值collection进行二进制搜索。

def binary(collection, target):
    """Binary search
    Takes a sorted list or tuple, collection, then searches for target
    Returns -1 if item isn't found. """
    length = len(collection)
    minimum = 0
    maximum = length - 1
    while minimum <= maximum:
        pivot = (minimum + maximum) // 2
        if collection[pivot] is target:
            return pivot
        elif collection[pivot] > target:
            minimum = pivot + 1
        else:
            maximum = pivot - 1
    return -1

如您所见,在target中找不到collection时,该函数返回-1。无论我做了什么,函数都返回-1。

>>> test = [1, 2, 3, 4, 5, 6]
>>> binary(test, 5)
-1
>>> binary(test, 1)
-1

是什么导致了这个问题?

2 个答案:

答案 0 :(得分:4)

你有这种情况倒退:

elif collection[pivot] > target:

切换它并进行搜索:

elif collection[pivot] < target:

对于它的价值,我通过在搜索中添加打印输出来了解这一点,看看发生了什么。如有疑问,请添加打印输出:

>>> binary([1, 2, 3], 1)
(min=0, max=2, pivot=1)
(min=2, max=2, pivot=2)
     ^ Oops

# After fixing...
>>> binary([1, 2, 3], 1)
(min=0, max=2, pivot=1)
(min=0, max=0, pivot=0)

顺便说一句,内置的bisect module执行二进制搜索。你不必自己写,除非你是为了教育价值。

答案 1 :(得分:1)

除了将条件测试更正为elif collection[pivot] < target:之外,您还使用“是”运算符来测试您是否找到了目标项目:

    if collection[pivot] is target:

您应该使用“==”代替:

    if collection[pivot] == target:

使用“is”测试两个东西是否实际上是同一个对象。在Python中,通常会将小型字符串和整数对象存储和回收,因此这可能有效。但是,在大多数情况下,它不会:

>>> a='abc'
>>> id(a)
2129839392
>>> b='ab'
>>> b+='c'
>>> id(b)
2129963136
>>> a
'abc'
>>> b
'abc'
>>> binary([a],a)
0
>>> binary([a],b)
-1