Python实现Connect4游戏 棋盘生成列表赋值异常问题排查
问题根源
你的原始代码出现这个现象,核心原因是Python里的列表是可变对象,直接赋值/append时传递的是对象的内存引用,而不是对象的独立副本。
拆解你原始代码的执行逻辑就能看得很清楚:
- 你在循环外只创建了1次单行列表
spaces_in_a_row,里面存了7个初始的"O"。 - 后续按棋盘高度循环6次往
board里追加内容时,每次追加的都是同一个单行列表的引用——也就是说你最终得到的board里,6个行元素本质上都指向内存里完全相同的那一个列表,根本没有生成6份独立的行。 - 这种情况下你执行
board[0][1] = "R",修改的是那个被所有行共享的唯一列表的第1位,自然所有位置都会同步显示修改后的"R",看起来就像整列都被改了。
另外你贴的原始代码里还有个笔误:定义的行变量叫spaces_in_a_row,append时写的是elements_in_row,直接运行会触发变量未定义的报错,应该是贴代码时手滑写错了。
为什么列表推导式写法能正常运行
你找到的两层列表推导写法,本质是把单行列表的创建逻辑放到了外层循环内部:
- 外层每遍历1次(对应生成棋盘的1行),内层的
["O" for _ in range(WIDTH_OF_GAME_BOARD)]就会重新执行一次,生成一个全新的、独立的单行列表。 - 最终
board里存的6个行列表分别对应内存里6个互不关联的独立对象,修改其中某一行的元素,自然不会影响其他行的内容。
如果要把你原来的循环写法改对,只要把单行列表的创建挪到行循环内部就行,效果和列表推导式完全一致:
HEIGHT_OF_GAME_BOARD = 6 WIDTH_OF_GAME_BOARD = 7 def generate_game_board(): board = [] for j in range(HEIGHT_OF_GAME_BOARD): # 每一行都在循环内新建独立列表,不共享引用 current_row = [] for i in range(WIDTH_OF_GAME_BOARD): current_row.append("O") board.append(current_row) return board
内容的提问来源于stack exchange,提问作者Ottaviano Augusto
相关产品推荐
相关产品推荐

