Python中While条件未在列表U为空时终止循环的问题排查
循环未在列表为空时终止导致除以零错误分析
问题重现
编写的循环预期在列表U为空时终止,但实际当U变为空后,循环仍会执行最后一段代码,触发除以零错误。相关代码如下:
def ATC(instance,K): pi=[] U = [i for i in range(instance.jobs)] t=0 p= sum(instance.pt) / len(U) while len(U)!=0: I=[] for j in U: I.append((instance.w[j]/instance.pt[j])*exp(-(max(instance.dd[j]-instance.pt[j]-t,0))/(K*p))) k = np.argmax(I) pi.append(U[k]) U.pop(k) print(U,len(U)) t = instance.Cmax(pi) p = sum([instance.pt[i] for i in U])/len(U) # 触发除以零错误的行 obj = instance.SumWjTj(pi) return pi,obj
循环过程中U和len(U)的打印结果显示,最后一轮循环后U已变为空列表,但错误仍会触发:
[0, 1, 2, 3, 4, 5, 7, 8, 9] 9 [0, 1, 2, 4, 5, 7, 8, 9] 8 [0, 1, 4, 5, 7, 8, 9] 7 [0, 1, 4, 7, 8, 9] 6 [0, 1, 4, 7, 9] 5 [0, 1, 4, 7] 4 [1, 4, 7] 3 [4, 7] 2 [7] 1 [] 0
原因解析
while len(U)!=0的判断逻辑是每一轮循环启动前执行一次,而非循环过程中实时监测:
- 当
U仅剩最后一个元素时,循环开始前len(U)=1,满足条件进入循环; - 在循环内部执行
U.pop(k)后,U变为空列表,但此时循环并未立即终止,会继续执行后续所有代码; - 直到当前轮次循环全部执行完毕,才会进行下一轮的
while条件判断,此时才会终止循环——但在最后一轮里,已经执行到了除以零的代码。
解决方案说明
添加if len(U)!=0:判断后,当U被清空时会跳过除以零的代码,避免错误:
# 修改后的代码片段 U.pop(k) print(U,len(U)) t = instance.Cmax(pi) if len(U)!=0: p = sum([instance.pt[i] for i in U])/len(U) obj = instance.SumWjTj(pi)
也可以在U.pop(k)后直接判断是否为空,提前终止循环,逻辑更直观:
U.pop(k) print(U,len(U)) if not U: break # 提前跳出循环,不再执行后续代码 t = instance.Cmax(pi) p = sum([instance.pt[i] for i in U])/len(U) obj = instance.SumWjTj(pi)
内容的提问来源于stack exchange,提问作者Agus RC
相关产品推荐
相关产品推荐

