You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python 3与Python 2二维列表初始化结果不一致问题排查

Python 2与Python 3列表推导式循环变量作用域差异问题

我尝试用列表推导式初始化二维列表时,发现Python 2和Python 3的执行结果存在差异,示例代码如下(导入语句用于在Python 2中使用Python 3的print语法):

from __future__ import print_function
ROW = 3
COL = 3

myList = [0 for i in range(ROW)]
#print('myList1 =', myList, 'len =', len(myList))
      
for i in range(len(myList)):
    #print('i =', i)
    myList[i] = [-1 for i in range(COL)]

#myList[0] = [-1 for i in range(COL)]

print('myList2 =', myList)

两个版本的输出分别为:

  • Python 3 输出:myList2 = [[-1, -1, -1], [-1, -1, -1], [-1, -1, -1]]
  • Python 2 输出:myList2 = [0, 0, [-1, -1, -1]]

执行赋值操作前,两个版本的执行过程一致;但循环内的赋值仅最后一次生效,手动在循环外执行myList[0] = ...这类操作却能正常更新元素,请问忽略了什么要点?


原因分析

问题出在Python 2与Python 3对列表推导式循环变量的作用域处理不同:

  • Python 3中,列表推导式的循环变量是局部变量,不会影响外层作用域的同名变量。外层循环的i会依次取0、1、2,三次赋值操作都能正常执行。
  • Python 2中,列表推导式的循环变量会泄露到外层作用域,和外层循环的i共用同一个变量。当第一次执行外层循环(i=0)时,内部的列表推导式[-1 for i in range(COL)]会把i覆盖为2(因为range(COL)遍历到最后一个值是2),此时外层循环的i也变成了2。接下来外层循环的下一次迭代,i会变成3,超出range(len(myList))(即range(3))的范围,循环直接终止,因此只有myList[2]被赋值,前两个元素保留初始值0。

解决方法

修改列表推导式中的循环变量名,避免和外层循环的变量冲突,比如把内部的i改成j:

from __future__ import print_function
ROW = 3
COL = 3

myList = [0 for i in range(ROW)]
      
for i in range(len(myList)):
    myList[i] = [-1 for j in range(COL)]

print('myList2 =', myList)

修改后,Python 2和Python 3的执行结果都会符合预期。

内容的提问来源于stack exchange,提问作者jml

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.25 12:54:27