多维列表元素异常变更:N皇后回溯算法调试求助
N皇后问题代码调试:修改piony[0][0]时piony[-1][0]同步变化的原因及修复
我正在实现N皇后问题的解决方案,编写代码计算n×n棋盘上放置n个皇后的可行方案数。以下是我的代码:
n = int(input()) piony = [[False for i in range(n)] for j in range(n)] skosy_lp = [[False for i in range(n)] for j in range(n)] skosy_pl = [[False for i in range(n)] for j in range(n)] figury = [-1] * n counter = 0 layer = 0 # list creating etc. piony list is containing vertical lines occupied by queens, skosy_lp # is containing lines oblique from left to right, skosy_pl - from right to left. # this is a backtracking algorithm # figury list is containing positions of queens. -1 means that the queen isn't placed while True: if layer == -1: break piony[layer] = piony[layer-1] skosy_pl[layer] = skosy_pl[layer-1] skosy_pl[layer].append(False) skosy_pl[layer].pop(0) skosy_lp[layer] = skosy_lp[layer-1] skosy_lp[layer].insert(0, False) skosy_lp[layer].pop(n) figury[layer]+=1 while figury[layer] < n and (piony[layer][figury[layer]] or skosy_lp[layer][figury[layer]]or skosy_lp[layer][figury[layer]]): figury[layer] +=1 if figury[layer] == n: figury[layer] = -1 piony[layer] = [False] * n skosy_pl[layer] = [False] * n skosy_lp[layer] = [False] * n layer-=1 else: if layer == n-1: counter+=1 layer-=1 else: print(piony) # I think there is a bug piony[layer][figury[layer]] = True skosy_pl[layer][figury[layer]] = True skosy_lp[layer][figury[layer]] = True layer+=1
调试时发现,当layer=0且figury[layer]=0时,执行piony[layer][figury[layer]] = True会同时修改piony[0][0]和piony[-1][0],请问这是什么原因?如何修复?
问题原因
核心是列表引用赋值导致的对象共享:
- 当layer=0时,
layer-1等于-1,对应piony列表的最后一个元素(Python中负数索引表示从末尾倒数)。 - 执行
piony[layer] = piony[layer-1]时,只是把piony[-1]的内存引用赋值给piony[0],两者指向同一个列表对象。此时修改piony[0][0],本质是修改这个共享的列表对象,所以piony[-1][0]也会同步变化。 - 同理,skosy_pl和skosy_lp的赋值逻辑也存在相同问题,会导致不同layer的列表互相影响。
修复方案
把引用赋值改为拷贝赋值,创建独立的列表副本,避免共享内存对象:
- 将
piony[layer] = piony[layer-1]修改为:piony[layer] = piony[layer-1].copy() # 或使用切片语法:piony[layer] = piony[layer-1][:] - 对skosy_pl和skosy_lp做同样修改:
skosy_pl[layer] = skosy_pl[layer-1].copy() skosy_lp[layer] = skosy_lp[layer-1].copy() - 这样每个layer对应的列表都是独立的新对象,修改其中一个不会影响其他layer的列表。
内容的提问来源于stack exchange,提问作者Filiput135
相关产品推荐
相关产品推荐

