python - 执行二进制搜索时列出索引超出范围错误
问题描述
我试图创建一个函数,它接受一个有序的数字列表和一个给定的数字,并决定给定的数字是否在列表内。我正在尝试使用二进制搜索来完成此任务。
我有两个步骤:
首先,我list1
只取list1
小于给定数字的数字,然后将这些数字附加到一个新列表中,称为newlist
.
接下来,在while
循环中,我基本上是取出所有小于中间数字的数字newlist
并将它们删除,重复该过程多次,直到newlist
. 从那里,我会将该数字与给定的数字进行比较。我的代码如下所示。
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))
我在第 36 行 ( if newlist[x] < newlist[round(len(newlist) / 2)]:
) 收到错误,表明列表索引超出范围。我认为问题在于随着newlist
越来越小,x
设置的值range(0, len(newlist) - 1)
保持不变??如果是这种情况,我不确定如何补救。非常感谢提前。
解决方案
问题就在这里:
for x in range(0, len(newlist) - 1):
if newlist[x] < newlist[round(len(newlist) / 2)]:
newlist.remove(newlist[x])
首先,您正在遍历列表
[0, 1, 2, ..., len(newlist) - 1]
这个列表是在你开始循环时生成的,这意味着如果len(newlist)
一开始是 7,那么列表将永远上升到 6,无论是否从 中删除东西newlist
,你稍后会这样做。这就是导致您的错误的原因,因为在某些时候您已经删除了足够的元素,以至于您的列表现在是三个元素,但是 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"
这本质上是for
在 python 中执行 C 或 Java 样式循环的方式,并且将避免此类问题。
我也了解您的代码中的逻辑存在问题,上述评论之一已指出这一点,并且更能触及您潜在问题的核心,但这至少可以解释为什么此错误发生在第一名,所以也许以后对你有帮助
推荐阅读
- php - 我正在尝试使用 php 面临问题的 json 请求
- google-apps-script - 从表格读取/写入突然变得异常缓慢
- java - 如何记录 pom 工件和版本
- bioinformatics - 尝试从 bwa-mem2 到 samblaster 的管道输出
- c# - C#:用 CSV 中的单列填充组合框
- excel - VBA - 按自定义日期格式过滤
- node.js - 防止 ''、null 或 undefined 字段保存在 MongoDb 中
- javascript - 设置了 async/await 的 Javascript 全局变量,但后来未定义
- azure - Azure - 如何识别与特定 NIC 或 VM 关联的任何 NSG?
- reactjs - 材料自动完成 - 选项更改时自动选择一个选项。反应