Python二维列表模式匹配问题:copy.deepcopy使用后代码失效排查
问题分析与解决
你的代码核心问题是遍历列表的同时直接修改原列表(调用remove(k)),这会破坏Python列表的迭代逻辑:当你删除当前遍历的元素时,列表的长度和元素索引都会发生变化,后续的迭代会跳过某些元素,导致不符合条件的元素没被删除,最终筛选结果出错。小列表测试时刚好没触发这个问题,但换成大的variations集合后,这个问题就暴露出来了。
修复方法一:用列表推导式生成新列表(推荐)
不要直接修改原列表,而是每次筛选后用符合条件的元素生成新列表替换原列表,逻辑更清晰也更安全:
import copy variations = [] for i in range(0, 512): subarr1 = list(bin((i // 64))[2:].zfill(3)) subarr2 = list(bin(((i - ((i // 64) * 64)) // 8))[2:].zfill(3)) subarr3 = list(bin((i - ((i // 8) * 8)))[2:].zfill(3)) arr = [subarr1, subarr2, subarr3] variations.append(arr) pbvariations = copy.deepcopy(variations) def findvariation(gamearr): global pbvariations for i in range(len(gamearr)): for j in range(3): val = gamearr[i][j] if val == "n": continue # 筛选出符合当前位置条件的元素,替换原列表 if val == "1": pbvariations = [k for k in pbvariations if k[i][j] == "1"] else: # val == "0" pbvariations = [k for k in pbvariations if k[i][j] == "0"] sample = [["1", "n", "1"], ["n", "0", "n"], ["n", "n", "n"]] findvariation(sample) print(pbvariations)
修复方法二:倒序遍历删除元素
如果一定要修改原列表,可以倒序遍历(从最后一个元素往前遍历),这样删除元素不会影响后续要遍历的元素索引:
import copy variations = [] for i in range(0, 512): subarr1 = list(bin((i // 64))[2:].zfill(3)) subarr2 = list(bin(((i - ((i // 64) * 64)) // 8))[2:].zfill(3)) subarr3 = list(bin((i - ((i // 8) * 8)))[2:].zfill(3)) arr = [subarr1, subarr2, subarr3] variations.append(arr) pbvariations = copy.deepcopy(variations) def findvariation(gamearr): global pbvariations for i in range(len(gamearr)): for j in range(3): val = gamearr[i][j] if val == "n": continue elif val == "1": # 倒序遍历,避免索引混乱 for idx in range(len(pbvariations)-1, -1, -1): if pbvariations[idx][i][j] != "1": del pbvariations[idx] else: for idx in range(len(pbvariations)-1, -1, -1): if pbvariations[idx][i][j] != "0": del pbvariations[idx] sample = [["1", "n", "1"], ["n", "0", "n"], ["n", "n", "n"]] findvariation(sample) print(pbvariations)
两种方法都能解决你的问题,其中列表推导式的写法更简洁易读,也更符合Python的惯用写法。
内容的提问来源于stack exchange,提问作者MOHD SAAD
相关产品推荐
相关产品推荐

