Python中if与else分支为何看似同时执行?二维列表赋值问题
问题分析与解决
这个问题的根源其实出在你创建二维列表的方式上,咱们一步步拆解来看:
核心问题:错误的二维列表创建方式
你用来生成网格的代码:
grid = [['.'] * 10] * 10
看起来是生成了10行10列的.矩阵,但实际上存在一个隐藏的陷阱:['.']*10会创建一个包含10个.的子列表,而后面的*10并没有生成10个独立的子列表,只是把同一个子列表对象重复引用了10次,放到外层列表里。也就是说,grid[0]、grid[1]……grid[9]其实都是指向同一个列表,它们是完全相同的内存引用。
为什么偶数/奇数网格表现不同?
再看你的invert函数:它会遍历每一行每一列,把.和X互相切换。但因为所有行都是同一个列表,当你处理第1行(row=0)时,已经把所有元素改成了X;处理第2行(row=1)时,又会把同一个列表的元素从X改回.;第3行再改成X,以此类推。
- 当网格大小是偶数(比如10行):每个元素会被修改10次(偶数次),最后又变回了初始的
.,所以两次打印都是全.的方阵。 - 当网格大小是奇数(比如9行):每个元素会被修改9次(奇数次),最终停在
X,所以看起来结果符合预期——但这只是修改次数奇偶性带来的巧合,本质上创建列表的方式还是错误的。
正确的解决方法
你需要创建10个独立的子列表,而不是重复引用同一个列表。推荐用列表推导式来实现:
# 两种写法效果一致,任选其一即可 grid = [['.' for _ in range(10)] for _ in range(10)] # 或者 grid = [['.'] * 10 for _ in range(10)]
这里的for _ in range(10)会循环10次,每次都生成一个全新的['.']*10子列表,这样外层列表里的每个子列表都是独立的对象,修改其中一行不会影响其他行。
现在重新运行你的代码,printGrid第一次会输出全.的方阵,调用invert后,第二次printGrid就会输出全X的方阵,和你的预期完全一致。
内容的提问来源于stack exchange,提问作者Saeed Baig
相关产品推荐
相关产品推荐

