Python二维数组行为异常排查:学生座位分配代码错误分析
代码错误分析与概念解释
问题背景
现有n名学生,每个学生对应偏好的行号,需要计算能在偏好空位就坐的学生数量(0表示空位),同时生成最终的教室座位数组,但代码运行结果不符合预期。
错误代码
n,m,k=map(int,input().split()) students=[int(x) for x in input().split()] classroom=[] count=0 rows=[0]*k for i in range(m): classroom.append(rows) for i in students: for j in range(k): if c[i-1][j]==1: continue else: c[i-1][j]=1 count+=1 break print(classroom)
问题现象
- 输入示例1:
5 2 2,学生数组为[1,1,2,1,1]- 预期教室输出:
[[1,1],[1,0]] - 实际教室输出:
[[1,1],[1,1]]
- 预期教室输出:
- 输入示例2:
5 2 2,学生数组为[1]- 预期教室输出:
[[1,0],[0,0]] - 实际教室输出:
[[1,0],[1,0]]
- 预期教室输出:
代码错误点
- 重复引用同一列表导致行同步变化:创建
classroom时,循环m次都往里面添加了同一个rows列表。Python里列表是可变对象,这就意味着classroom里的所有行其实都是同一个列表的“分身”——修改任意一行的元素,所有行都会跟着改变,这直接导致了示例中结果不符合预期。 - 变量名错误:代码中使用了未定义的变量
c,实际应该用classroom,否则运行时会直接抛出未定义错误。
相关概念与逻辑解释
- 可变对象的引用特性:Python里像列表、字典这类可变对象,赋值或者添加到其他列表时,传递的是对象的引用(相当于指向内存地址的指针),而不是复制整个对象。你原来的代码里
rows = [0]*k只创建了一个列表,每次append(rows)都是把这个列表的引用加到classroom里,所以classroom里的所有行本质上是同一个东西。 - 正确生成独立行的方法:要让每一行都是独立的列表,必须在循环里每次生成新的列表,比如把创建
classroom的代码改成:
这样每次循环都会生成一个全新的for i in range(m): classroom.append([0]*k)[0]*k列表,各行之间互不影响。
修正后的代码
n,m,k=map(int,input().split()) students=[int(x) for x in input().split()] classroom=[] count=0 # 每行创建新列表,避免引用复用 for i in range(m): classroom.append([0]*k) for stu_row in students: row_idx = stu_row - 1 # 转换为Python的0索引 for col_idx in range(k): if classroom[row_idx][col_idx] == 1: continue classroom[row_idx][col_idx] = 1 count += 1 break print(classroom) print(f"成功在偏好座位就坐的学生数:{count}")
内容的提问来源于stack exchange,提问作者Rohith Damarla
相关产品推荐
相关产品推荐

