Python 二分查找总是返回目标未找到值

发布于 2024-09-18 07:51:07 字数 856 浏览 8 评论 0原文

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

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

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

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

是什么导致了这个问题?

I've written the following code to do a binary search for a value, target, in a list or tuple, 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

As you can see, when target isn't found in collection, the function returns -1. No matter what I've done, the function has returned -1.

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

What's causing this problem?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

萌吟 2024-09-25 07:51:07

你有这样的条件:

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 模块执行二分搜索。您不必自己编写,除非您这样做是为了教育价值。

You have this condition backwards:

elif collection[pivot] > target:

Switch it and the search works:

elif collection[pivot] < target:

For what it's worth, I figured this out by adding a printout to your search to see what's happening. When in doubt, add a printout:

>>> 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)

By the way, the built-in bisect module performs binary searches. You don't have to write your own, unless you're doing it for educational value.

星光不落少年眉 2024-09-25 07:51:07

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

    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

In addition to correcting your condition test to elif collection[pivot] < target: , you used the "is" operator for testing whether you have found your target item:

    if collection[pivot] is target:

You should use "==" instead:

    if collection[pivot] == target:

Using "is" tests whether two things are actually the same object. In Python, quite often small string and integer objects turn out to be stored and recycled, so this might work. However, in most cases, it will not:

>>> a='abc'
>>> id(a)
2129839392
>>> b='ab'
>>> b+='c'
>>> id(b)
2129963136
>>> a
'abc'
>>> b
'abc'
>>> binary([a],a)
0
>>> binary([a],b)
-1
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文