CS50 Tideman项目Python动态投票网格计票异常求助
CS50 Tideman项目动态计票网格异常问题解决
问题现象
在完成CS50的Tideman项目时,生成候选人得票记录网格遇到以下问题:
- 使用预先定义的固定大小网格时,计票功能正常,各行计票结果独立。
- 根据候选人数量动态生成网格后,计票时所有行数据完全相同,无法得到正确的独立计票结果。
固定网格定义代码:
candidates = ['Bob', 'Joe', 'Tom', 'Mike'] grid = [ [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0] ]
动态网格生成代码(有问题版本):
candidates = ['Bob', 'Joe', 'Tom', 'Mike'] grid = [] rows = [] for i in candidates: rows.append(0) for j in candidates: grid.append(rows)
计票后固定网格输出(正常):
[0, 0, 1, 0] [1, 0, 1, 0] [0, 0, 0, 0] [1, 1, 1, 0]
计票后动态网格输出(异常):
[2, 1, 3, 0] [2, 1, 3, 0] [2, 1, 3, 0] [2, 1, 3, 0]
问题原因
动态生成网格的代码中,rows是一个单一的列表对象。每次执行grid.append(rows)时,都是把同一个列表的引用添加到grid中,而非创建新的列表。这意味着grid里的所有行都指向内存中的同一个列表,修改任意一行的元素都会同步影响所有行。
而固定网格的每个子列表都是独立创建的新对象,彼此之间没有引用关联,因此修改某一行不会影响其他行。
解决方案
修改动态网格生成逻辑,确保每次添加到grid的都是新的独立列表,而非重复引用同一个列表。
方法1:循环内创建新列表
candidates = ['Bob', 'Joe', 'Tom', 'Mike'] grid = [] for _ in candidates: # 每次循环生成一个新的全0子列表 grid.append([0] * len(candidates))
方法2:列表推导式(更简洁)
candidates = ['Bob', 'Joe', 'Tom', 'Mike'] grid = [[0] * len(candidates) for _ in candidates]
这两种方式都会为grid的每一行创建独立的列表对象,计票时修改某一行的元素不会影响其他行,最终结果将与固定网格一致。
内容的提问来源于stack exchange,提问作者Jalu589
相关产品推荐
相关产品推荐

