Search code examples
pythonreferencestackminimum

Stack DataStructure Reference Issue in Python


I am trying to build a stack adt with an additional method of findMin() which returns the minimum integer in a stack. I am doing this using 2 stacks I built in python(note outside of this class the stacks work fine).

from StackandQueueADT import Stack


class MinStack:
'This class has same functionality as a regular stack with 1 extra method that finds min of stack'
'it will use a min stack to keep track of min number'
def __init__(self):
    self.myStack = Stack()
    self.minStack=Stack()
    
def isEmpty(self)->bool:
    if(self.myStack.isEmpty()):
        return True
    return False

        
def push(self,x)-> None: 
    if(self.isEmpty() or x <= self.minStack.peek()):
            self.minStack.push(x) 
    self.myStack.push(x)


def pop(self)->int:
    if(not self.minStack.isEmpty() and self.myStack.peek() == self.minStack.peek()):
        print("what is happening with current stack Before?: " + str(self.myStack.peek()))
        print("pop minstack: " + str(self.minStack.pop()))
        print("what is happening with current stack After?: " + str(self.myStack.peek()))
    return self.myStack.pop()
def peek(self)->int:
    if(self.myStack.isEmpty()):
        return -1
    return self.myStack.peek()
def getMin(self)->int:
    if(self.minStack.isEmpty()):
        return -1
    return self.minStack.peek()

The issue I am having is in the pop() method. Somehow if it goes in the if statement removing the element from the minstack it also removes the element from myStack as well. That is it removes the element from myStack before "return self.myStack.pop()" is called.

I used the following sample to test this out:

minStack = MinStack()
minStack.push(-2)
minStack.push(0)
minStack.push(-3)
print("pop: "  + str(minStack.pop()))

In this example somehow -3 is popped from both minStack and myStack implicitly when I only popped it from minStack. Note testing each stack individually works fine but when doing it this way somehow it looks like the same reference is passed to both stacks.

If needed this is my stack class:

class Stack:
stack=[]
top = -1

def isEmpty(self):
    if self.top==-1:
        return True
    return False
def push(self,data):
    self.top = self.top+1
    self.stack.insert(self.top,data)
def pop(self):
    if self.isEmpty():
        print("The stack is empty!,nothing to pop")
        return None
    value = self.stack[self.top]
    self.stack.pop(self.top)
    self.top = self.top-1
    return value
def peek(self):
    if self.isEmpty():
        print("The stack is empty!")
        return -1
    
    return self.stack[self.top]

Solution

  • class Stack:
        stack=[]
    
    a = Stack()
    b = Stack()
    
    print("a's stack", a.stack) # a's stack []
    a.stack.append(1)
    print("b's stack", b.stack) # b's stack [1]
    

    In python, variable defined under class is class level variable which is shared among all instances of the class. In your code self.minStack and self.myStack are different instances but they share same stack variable in Stack class.

    When you access by self.stack/top it will create independent reference for that instance, but stack reference still refer to same list object. You might want to do

    class Stack:
        def __init__(self):
            self.stack = []
            self.top = -1
    

    It's quite confusing and long topic to go thoroughly so I suggest you read about class variables.