我正在尝试构建一个函数,该函数提供给定的列表或数字字符串(对于字符串,数字用“,”分隔),目标数字查找最后一个可以到达目标的值的数量。只有吃掉一个等于或小于自己的数字,数字才能增加1,吃掉较小的数字后,较小的数字将从列表中删除。每个号码列表都会重置为原始号码。我已经接近了,但是我一直收到索引错误,而且不确定如何解决
def cannibal(l, target):
newl = l
count = 0
i = 0
listlen = len(newl)
try:
newl = l.split(",")
newl.sort(reverse = True)
newl = list(map(int, newl))
print (newl)
except:
newl.sort(reverse = True)
print (newl)
finally:
while i < len(newl):
print ("index is ",i)
if newl[i] == target:
print ("match found at ", i)
count += 1
i += 1
continue
if newl[i] > target:
i += 1
continue
for j in range(i+1,listlen-1):
print ("list length is",listlen)
while newl[i] > newl [j] and j<listlen:
print (newl[i]," is eating ",newl[i+1])
newl.remove(newl [i+1])
newl[i] = newl[i]+1
listlen = len(newl)
print (newl)
if newl[i] == target:
print ("match found at ", i)
count += 1
i += 1
break
i += 1
print (count)
return count
给出cannibal([27, 9, 3, 8, 11], 50)
后,它将返回IndexError: list index out of range
并指向while newl[i] > newl [j] and j<listlen:
答案 0 :(得分:2)
>>> cannibal([27, 9, 3, 8, 11], 50)
[27, 11, 9, 8, 3]
index is 0
list length is 5
27 is eating 11
[28, 9, 8, 3]
28 is eating 9
[29, 8, 3]
29 is eating 8
[30, 3]
30 is eating 3
[31]
Traceback (most recent call last):
File "<pyshell#169>", line 1, in <module>
cannibal([27, 9, 3, 8, 11], 50)
File "<pyshell#168>", line 36, in cannibal
while newl[i] > newl [j] and j<listlen:
IndexError: list index out of range
我运行了您提到的失败的测试用例。乍一看,似乎存在不适当的退出条件。经过进一步检查,似乎您的最里面的while循环最终被迫评估会引发IndexError的条件。
当我在while循环的末尾插入print(newl, i, j)
时,我们会得到以下结果:
>>> cannibal([27, 9, 3, 8, 11], 50)
[27, 11, 9, 8, 3]
index is 0
list length is 5
27 is eating 11
[28, 9, 8, 3]
[28, 9, 8, 3] 0 1
28 is eating 9
[29, 8, 3]
[29, 8, 3] 0 1
29 is eating 8
[30, 3]
[30, 3] 0 1
30 is eating 3
[31]
[31] 0 1
Traceback (most recent call last):
File "<pyshell#175>", line 1, in <module>
cannibal([27, 9, 3, 8, 11], 50)
File "<pyshell#174>", line 37, in cannibal
while newl[i] > newl [j] and j<listlen:
IndexError: list index out of range
希望现在清楚了问题所在。
在while循环中的某个时刻,您最终得到newl = [31]
,i = 0
和j = 1
。
计算条件while newl[i] > newl [j] and j<listlen
时,当然newl[0] > newl[1]
会中断功能,因为newl[1]
不存在。
要阻止发生 的错误,最简单的方法是添加一个标志以退出for循环。
def cannibal(l, target):
newl = l
count = 0
i = 0
listlen = len(newl)
try:
newl = l.split(",")
newl.sort(reverse = True)
newl = list(map(int, newl))
print (newl)
except:
newl.sort(reverse = True)
print (newl)
finally:
while i < len(newl):
print ("index is ",i)
if newl[i] == target:
print ("match found at ", i)
count += 1
i += 1
continue
if newl[i] > target:
i += 1
continue
break_out = False
for j in range(i+1,listlen-1):
if break_out: break
print ("list length is",listlen)
while newl[i] > newl [j] and j<listlen:
print (newl[i]," is eating ",newl[i+1])
newl.remove(newl [i+1])
newl[i] = newl[i]+1
listlen = len(newl)
print (newl)
print(newl, i, j)
if newl[i] == target:
print ("match found at ", i)
count += 1
i += 1
print(newl, i, j)
break
if i >= len(newl) or j >= len(newl):
print ("loop is broken")
break_out = True
break
i += 1
print (count)
return count
但是,我相信问题会更加严重。我不完全了解您打算如何使用此功能,但我有种直觉,您不希望newl
在for循环的第一次迭代之后永久成为[31]
。