Python递归类对象与成员变量问题:排列生成代码输出异常排查
问题分析:生成带重复排列时输出空列表的原因及修复
我来帮你定位这个问题——核心原因出在Python列表的引用传递机制上,你在代码里一直在操作同一个列表对象,导致最终所有添加到end_set里的列表都被清空了。
问题根源详解
当你在helpfunc里执行self.end_set.append(seen)的时候,你并没有添加一个新的列表,而是把seen这个列表的引用存进了end_set。之后你执行del seen[-1],会直接修改这个被引用的列表本身。等到递归结束时,所有存进end_set的引用指向的都是同一个已经被清空的列表,所以输出全是空的。
修复方案
你需要在把seen添加到end_set的时候,创建一个它的副本,而不是直接存引用。修改helpfunc里的终止条件部分即可:
关键修改
原来的代码:
if depth == 0: self.end_set.append(seen)
改成:
if depth == 0: self.end_set.append(seen.copy()) # 或者用 self.end_set.append(list(seen))
完整修复后的代码
另外还调整了几个小细节(比如适配Python3语法、移除冗余变量):
class permcom: def __init__(self, INPUT_SET, IS_PERM, REPETITION): self.end_set = [] self.input_set = INPUT_SET self.is_perm = IS_PERM self.repetition = REPETITION def helpfunc(self, seen, depth, current): if depth == 0: self.end_set.append(seen.copy()) # 关键修复:添加列表副本 else: for i in range(len(self.input_set)): if self.repetition: seen.append(self.input_set[i]) if self.is_perm: self.helpfunc(seen, depth - 1, 0) else: self.helpfunc(seen, depth - 1, i) del seen[-1] # 返回带重复的排列 def rapwr(INPUT_SET, subset_size): instance = permcom(INPUT_SET, True, True) instance.helpfunc([], subset_size, 0) # 直接传空列表,无需额外变量 return instance.end_set A = [1,2,3] B = rapwr(A, 2) for item in B: print(item)
运行这段代码就能得到你预期的输出:
[1, 1]
[1, 2]
[1, 3]
[2, 1]
[2, 2]
[2, 3]
[3, 1]
[3, 2]
[3, 3]
补充说明
创建列表副本的作用是:生成一个和当前seen内容完全一致但独立的新对象,后续修改原seen的操作不会影响这个副本,这样end_set里的每个元素都能保存递归到对应深度时的列表状态。
内容的提问来源于stack exchange,提问作者EllipticalInitial
相关产品推荐
相关产品推荐

