使用popleft实现队列出队返回完整栈问题排查(不可修改核心方法)
问题分析:队列取出的是栈对象而非栈内元素
嘿,我来帮你捋清楚这里的问题所在!
你当前代码的核心问题是:你把整个stack1对象存入了队列,而不是把栈里的单个元素存进去。咱们一步步拆解你的代码流程:
- 你先给
stack1推入了['stone', 'atone'],这时候栈里只有这一个元素; - 然后你执行
queue1.enqueue(stack1)——这一步是把整个stack1这个栈对象放进了队列,队列里现在有一个元素:就是这个栈对象的引用; - 之后你又给
stack1推入了另外两个元素,这时候栈里的内容变成了三个元素。注意哦!因为Python里对象是按引用传递的,队列里存的stack1和你外面操作的stack1是同一个东西,所以栈里的变化会直接反映到队列里的那个对象上; - 当你调用
dq = queue1.dequeue(),dq拿到的就是那个完整的栈对象,所以调用dq.toString()自然会输出整个栈的所有元素,也就是你看到的[['stone', 'atone'], ['stone', 'shone'], ['stone', 'scone']]。
那怎么拿到你想要的['stone','atone']呢?根据你说的不能修改enqueue、dequeue和__init__方法,有两种思路:
思路1:存入队列时,存栈内的元素而非栈对象
如果你本来就想让队列存储栈里的元素,那不要直接把整个栈丢进去,而是把栈里的元素逐个入队。不过这需要你的MyStack有弹出元素的方法,先给它加一个:
class MyStack: def __init__(self): self._data = [] def push(self, value): self._data.append(value) def size(self): return len(self._data) def toString(self): return str(self._data) # 新增pop方法,弹出栈顶元素 def pop(self): if self.size() > 0: return self._data.pop() return None
然后修改入队的逻辑:
# 把栈里的元素逐个弹出并存入队列 while stack1.size() > 0: queue1.enqueue(stack1.pop())
这样队列里存的就是单个的元素,调用dequeue()就能拿到['stone','atone']啦(不过注意栈是后进先出,所以弹出的顺序会反过来,如果要保持原顺序,可能需要先把元素存到另一个栈里反转一下)。
思路2:取出栈对象后,获取栈内的目标元素
如果你必须把栈对象存入队列,那取出后可以直接访问栈里的第一个元素(也就是你最早推入的那个)。不过直接访问私有属性_data不太规范,最好给MyStack加一个获取栈底元素的方法:
class MyStack: # ... 其他方法不变 def get_bottom_element(self): if self.size() > 0: return self._data[0] return None
然后取出的时候这样用:
dq = queue1.dequeue() print(dq.get_bottom_element()) # 输出['stone', 'atone']
当然如果临时测试的话,直接print(dq._data[0])也能得到结果,但不推荐在正式代码里这么做。
总结一下:你之前混淆了栈对象本身和栈内部存储的元素,队列里存的是栈的引用,所以取出后操作的是整个栈,而不是你想要的那个单个元素~
内容的提问来源于stack exchange,提问作者Sarah Collins
相关产品推荐
相关产品推荐

