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"