Python 执行二进制搜索时列表索引超出范围错误

Python 执行二进制搜索时列表索引超出范围错误,python,list,while-loop,Python,List,While Loop,我试图创建一个函数,它接受一个有序的数字列表和一个给定的数字,并决定给定的数字是否在列表中。我正在尝试使用二进制搜索来完成这项任务 我有两个步骤: 首先,我通过只取list1中小于给定数字的数字,然后将这些数字添加到一个名为newlist的新列表中,使list1更小 下,在 循环中,我基本上取所有小于“代码”>“NealList”中间的数字,并删除它们,重复这个过程,直到在 NealList中只有一个数字。从那里,我将把这个数字与给定的数字进行比较。我的代码如下所示 list1 = [1, 3,

我试图创建一个函数,它接受一个有序的数字列表和一个给定的数字,并决定给定的数字是否在列表中。我正在尝试使用二进制搜索来完成这项任务

我有两个步骤:

首先,我通过只取
list1
中小于给定数字的数字,然后将这些数字添加到一个名为
newlist
的新列表中,使
list1
更小

下,在<代码> 循环中,我基本上取所有小于“代码”>“NealList”中间的数字,并删除它们,重复这个过程,直到在<代码> NealList中只有一个数字。从那里,我将把这个数字与给定的数字进行比较。我的代码如下所示

list1 = [1, 3, 5, 6, 8, 14, 17, 29, 31]
number = 7

def func(list1, number):
    newlist = []
    for x in list1:
        if x < number:
            newlist.append(x)
        else:
            continue

    while len(newlist) > 1:
        for x in range(0, len(newlist) - 1):
            if newlist[x] < newlist[round(len(newlist) / 2)]:
                newlist.remove(newlist[x])
            else:
                continue

    if newlist[0] == number:
        return True
    else:
        return False

print(func(list1, number))
list1=[1,3,5,6,8,14,17,29,31]
数字=7
def func(列表1,编号):
新列表=[]
对于列表1中的x:
如果x<数字:
newlist.append(x)
其他:
持续
而len(newlist)>1:
对于范围(0,len(newlist)-1)中的x:
如果newlist[x]

我在第36行收到一个错误(
如果newlist[x]
),列表索引超出范围。我认为问题在于,随着
newlist
越来越小,由
range(0,len(newlist)-1)
设置的
x
值保持不变??如果是这样的话,我不确定如何补救。非常感谢

问题就在这里:

for x in range(0, len(newlist) - 1):
    if newlist[x] < newlist[round(len(newlist) / 2)]:
        newlist.remove(newlist[x])
此列表是在启动循环时生成的,这意味着如果
len(newlist)
在开始时为7,则无论是否从
newlist
中删除内容,列表将始终上升到6,稍后您将执行此操作。这就是导致错误的原因,因为在某一点上,您已经删除了足够多的元素,因此列表现在(比如)大了三个元素,但是python正在尝试访问第五个元素,因为它所迭代的列表不是
newlist
,而是
[0,1,2,3,4,5,6]

要解决此问题,您可以(例如)用以下内容替换for循环:

x = 0
while x < len(newlist - 1):
    if newlist[x] < newlist[round(len(newlist) / 2)]:
        newlist.pop(x)  # simple way of saying "remove item at index x"
x=0
当x
这本质上是在python中为循环执行C或Java风格的
,并将避免此类问题


我还了解到,您的代码中存在逻辑问题,这在上面的一条评论中已经指出,并且更深入到了根本问题的核心,但这至少解释了为什么会首先发生此错误,因此,也许这对您将来会有帮助

因此,在列表1中使用
数字
检查不是一个选项?虽然这可能不是一个直接的答案,但在这一点上,我真的鼓励您尝试调试器,如果您还没有尝试过的话。只需插入一行:
importpdb;pdb.在带有
if
的行之前设置_trace()
,然后像往常一样重新运行程序。在出现的提示中,键入
(如
!newlist[x]
,或
!x
等)查看变量的值。键入
c
继续运行程序直到结束或另一个断点,或键入
n
执行下一行并停止。相信我,这是一个有趣的练习@伊戈尔:这肯定是一个选择,但我正试图用多种方法解决这个问题。我会看看的。谢谢。请尝试在
.remove()
之后放置一个
中断符。这将终止
for
循环,并返回
while
循环,如果其条件不再为真,该循环将终止。另外,您是否知道
list.remove(value)
会删除给定值的第一个匹配项?如果您的列表包含两个相同值的匹配项,并且
list[x]
引用了第二个匹配项,则错误的匹配项将被删除。使用
del list[x]
代替。非常感谢。
x = 0
while x < len(newlist - 1):
    if newlist[x] < newlist[round(len(newlist) / 2)]:
        newlist.pop(x)  # simple way of saying "remove item at index x"