Python Stack类反转方法复用旧测试数据致后续测试异常问题
问题分析与修复
核心问题根源
你遇到的旧数据残留问题,本质是Python可变默认参数的陷阱,以及reverse方法的实现导致的共享状态:
Stack.__init__的默认参数错误:
当定义def __init__(self, arr=[])时,可变默认列表[]只会在函数定义时创建一次。所有通过Stack()(无参数)创建的实例,都会共享同一个底层列表。你的reverse方法中每次创建res = Stack()时,都会复用这个共享列表,导致前一次测试的元素被保留下来。reverse方法修改原栈并复用状态:
执行self.pop()会直接修改原栈的内容,同时由于res的底层列表是共享的,每次调用reverse都会把新元素追加到同一个列表中,最终导致所有测试用例的元素累积。
修复步骤
1. 修复Stack类的初始化方法
把可变默认参数替换为None,在函数内部初始化独立的列表,确保每个Stack实例拥有自己的底层存储:
class Stack: def __init__(self, arr=None): # 每个实例创建独立的列表,避免共享 self.stack = arr.copy() if arr is not None else [] # 其他方法保持不变...
2. 修改reverse方法,避免修改原栈
当前的reverse会清空原栈,且复用共享列表。修改为每次生成全新的反转栈,同时保留原栈内容:
def reverse(self): # 基于原栈副本操作,不修改原栈 temp_stack = Stack(self.stack.copy()) reversed_stack = Stack() while temp_stack: reversed_stack.push(temp_stack.peek()) temp_stack.pop() return reversed_stack
3. 匹配测试用例的预期结果(可选)
从测试用例注释来看,你需要的功能似乎不是反转整个栈,而是删除栈中的中间元素(比如Test Case 01删除元素1)。如果是这样,可以实现对应的方法:
def remove_middle(self): if not self.stack: return self mid = len(self.stack) // 2 temp_stack = Stack() # 弹出中间位置之前的元素 for _ in range(mid): temp_stack.push(self.stack.pop()) # 移除中间元素 self.stack.pop() # 将元素放回原栈 while temp_stack: self.stack.append(temp_stack.peek()) temp_stack.pop() return self
测试时调用remove_middle而非reverse即可得到注释中的预期结果。
修复后的完整代码
class Stack: def __init__(self, arr=None): self.stack = arr.copy() if arr is not None else [] def __len__(self): return len(self.stack) def __str__(self): res = '' for each in self.stack: res += str(each) + ' ' return res def push(self, number): self.stack.append(number) def pop(self): if self.stack: return self.stack.pop() return None def peek(self): if self.stack: return self.stack[-1] return None def reverse(self): temp_stack = Stack(self.stack.copy()) reversed_stack = Stack() while temp_stack: reversed_stack.push(temp_stack.peek()) temp_stack.pop() return reversed_stack if __name__ == '__main__': # Test Case 01 test1 = Stack([-2,0,1,4,5]) print(f'Stack Before: {test1}') test1_reversed = test1.reverse() print(f'Stack After: {test1_reversed}\n') # Test Case 02 test2 = Stack([1,2,3,4,5,6]) print(f'Stack Before: {test2}') test2_reversed = test2.reverse() print(f'Stack After: {test2_reversed}\n') # Test Case 03 test3 = Stack(['a', 'b', 'c']) print(f'Stack Before: {test3}') test3_reversed = test3.reverse() print(f'Stack After: {test3_reversed}\n') # Test Case 04 test4 = Stack([8, -2, 55, 12, -47, 10]) print(f'Stack Before: {test4}') test4_reversed = test4.reverse() print(f'Stack After: {test4_reversed}')
修复后输出
每个测试用例的结果独立,不会累积旧数据:
Stack Before: -2 0 1 4 5 Stack After: 5 4 1 0 -2 Stack Before: 1 2 3 4 5 6 Stack After: 6 5 4 3 2 1 Stack Before: a b c Stack After: c b a Stack Before: 8 -2 55 12 -47 10 Stack After: 10 -47 12 55 -2 8
内容的提问来源于stack exchange,提问作者Areeb Hussain Qureshi
相关产品推荐
相关产品推荐

