为何这段Python列表推导式会触发列表索引越界错误
问题原因与解决方法
你的代码触发IndexError: list index out of range的核心问题是列表推导式的循环顺序搞反了,执行逻辑和你预想的完全不一致。
错误执行逻辑
你写的推导式:
[j for j in range(len(grid[i])) for i in range(len(grid))]
Python的列表推导式遵循「左循环为外层,右循环为内层」的规则,等价于下面的嵌套循环:
result = [] # 先执行外层循环:此时i还未被后面的循环赋值(或是全局环境中已存在的旧值) for j in range(len(grid[i])): # 后执行内层循环 for i in range(len(grid)): result.append(j)
如果你的环境里之前i被设成了大于0的数(比如i=1),grid[i]就会因为超出grid = [[]]的索引范围(只有索引0)而触发IndexError;如果i没被定义过,会触发NameError。
正确写法
你想要的逻辑是先遍历i,再遍历每个i对应的j,所以要把循环顺序反过来:
[j for i in range(len(grid)) for j in range(len(grid[i]))]
等价于符合直觉的嵌套循环:
result = [] for i in range(len(grid)): for j in range(len(grid[i])): result.append(j)
此时i会先被赋值为0,len(grid[0])是0,range(0)为空,最终得到空列表,不会报错。
补充说明
你单独运行[j for j in range(len(grid[0]))]没问题,是因为这里直接用了确定的索引0,而错误推导式里的grid[i]在执行时i的取值根本不是你预想的0,要么是全局旧值,要么未定义。
内容的提问来源于stack exchange,提问作者Helin Wang
相关产品推荐
相关产品推荐

