Multiple Stacks in Class

Good day community,

I am requesting your expertise on this stage of my learning path.
I have just dived into classes, for the 3rd time learning it, and I’ve found something which makes no sense to me. I have gone over the code a few times in visualizer, step by step, trying to understand why I get the result, 3.
I notice 3 is deleted from the stackObject1 instance list when executing stackObject2.push(stackObject1.pop()), but why does it keep it in pop(self), and how is it passing it to stackObject2, and printing that value, when the last function call, is to pop the value?

class Stack:
    def __init__(self):
        self.__stackList = []

    def push(self, val):
        self.__stackList.append(val)

    def pop(self):
        val = self.__stackList[-1]
        del self.__stackList[-1]
        return val


stackObject1 = Stack()
stackObject2 = Stack()

stackObject1.push(3)
stackObject2.push(stackObject1.pop())

print(stackObject2.pop())
  • You set the stackObject1’s last entry to 3 via stackObject1.push(3).
  • Then you pop stackObject1 by setting val to the most recent entry (which is 3).
  • Then you delete the most recent entry in __stackList, but val still equals 3.
  • Then you return val (which is 3) and push it to stackObject2.
  • Then you pop stackObject2 in the same manner as stackObject1; therefore, it also returns 3.
  • If you were to try and access stackObject2.__stackList[-1] after the last pop, you will see that it should be empty.

Pop is supposed to return whatever the last value was, but also delete it, so it is working exactly as expected.

Thanks Isaac,

Ok, so i think i get it.

Does val remain 3, because when the pop function is run, it is calling a value which was loaded from its superclass(push)

So pop will merely inherit val=3, but can have no effect on ever deleting the value it is calling from push? Because the delete function in pop, is pertinent to the val it recently loaded in that function, not val in the push function.

Am i on the right track here?

There is no inheritance in this. push sets the most recent stack entry to whatever value you give it. pop returns the most recent stack entry while also removing it from the stack.

So, the following pop is returning 3 and passing it to push which, in return, sets the second stack instance to have an entry of 3.

stackObject2.push(stackObject1.pop())

When you call the following, it returns the most recent entry of 3, but afterward it will no longer be in the second stack.

print(stackObject2.pop())

Val remains 3 because you set it to 3 here:

    def pop(self):
        val = self.__stackList[-1]

You’ve created a new variable and set it to 3.

You’ve removed 3 from __stackList, but you didn’t remove 3 from val. So when we return val immediately after, it is still 3.

        del self.__stackList[-1]

I think maybe you are getting confused and thinking that del self.__stackList[-1] should have destroyed 3, and anything that had referenced that 3 also no longer should have 3, but that is simply not the case. All del does is remove all references of 3 from __stackList. If whatever was in __stackList is no longer referenced by any other variable, at some point, it would be garbage collected. val is still referencing 3, but __stackList is not.

2 Likes

Thank you again Isaac, I am definitely seeing the light on this.
I had definitely confused myself when I came across the delete function. That’s all I saw and missed the whole point in learning stacking.

You’ve cleared up a lot for me on this topic with your explanations! Much appreciated! :+1: :+1:

Noting, just for completeness:

The variable val disappears when you return from the pop function,
but the object it references (3) it still referenced by the return
machinery, and that reference gets saved/used by whatever uses the
return value of the .pop() function.

Also, del somelist[-1] is a slightly unusual way to remove the
rightmost element from a list. The list class itself has a .pop()
method :slight_smile: Maybe that would just have hidden the mechanism from you!

Cheers,
Cameron Simpson cs@cskk.id.au

1 Like

Thanks Cameron,

Yip, true. so then self.__stackList.pop() instead of del self.__stackList[-1] ?

What i am realizing the more i read up about STACK, is that it’s a real world purposeful structure, for Data Structures to efficiently access and edit data. I was looking at it from an entirely different point of view.

They are not quite the same. self.__stackList.pop() removes the item at the top of the stack and returns it. del self.__stackList[-1] just removes it.

The reason your Stack.pop method is implemented the way it is, is to serve as an educational example. This would achieve the same result:

    def pop(self):
        return self.__stackList.pop()

but that wouldn’t be very helpful for someone trying to understand what pop actually does.

2 Likes