A List as a Stack
Python has no stack type, and it does not need one. A list already has a method that adds at the end, append(), and a method that removes from the end and hands the item back, pop(). Use only those, and the list behaves exactly like a stack. The end of the list is the top.
1Each stack operation is one line of list code
| Stack operation | List code | What it gives back |
|---|---|---|
| push | stack.append(item) | None — nothing useful |
| pop | stack.pop() | the last item, which is removed |
| peek | stack[-1] | the last item, which stays |
| isEmpty | len(stack) == 0 | True or False |
| size | len(stack) | how many items there are |
stack = []
stack.append(10)
stack.append(20)
stack.append(30)
print('stack :', stack)
print('top :', stack[-1])
item = stack.pop()
print('popped:', item)
print('stack :', stack)stack : [10, 20, 30] top : 30 popped: 30 stack : [10, 20]
stack = []An empty list is an empty stack. There is nothing else to set up.
stack.append(30)Adds 30 at the end of the list — on top of 20.
stack[-1]Index -1 is the last item, so this is peek. It reads the top and changes nothing.
item = stack.pop()Removes the last item and hands it back. The name item catches it; without a name, the 30 would simply be thrown away.
2Press the code, watch the stack
Every button is one line of Python. The pile and the list under it are the same thing, drawn two ways.
——The list already holds three numbers. 30 was added last, so it sits at the end — and the end is the top.
print(stack) showsThe bottom of the pile is stack[0], printed first. The top is the last item, stack[-1].
3The list is a stack lying on its side
Before the pop, print(stack) showed [10, 20, 30]. Stand that list up and 10 is at the bottom, 30 on top. The printout reads bottom first, so the top is always the right-hand end.
[10, 20, 30]→[10025, 254923, 1297653, 31498, 92765]. The last number, 92765, is the top — and the question's expected output does print 92765 first.4Peek reads the top; pop removes it
stack = [10, 20, 30]
print(stack[-1], len(stack))
print(stack[-1], len(stack))
print(stack.pop(), len(stack))
print(stack.pop(), len(stack))30 3 30 3 30 2 20 1
Peek twice and you get 30 twice, with the length still 3. Pop twice and you get two different items, because each pop removes the one before the next pop looks.
5Why the end, and not the front?
Could the front of the list be the top instead? Yes. insert(0, item) adds at the front and pop(0) removes from the front, and a list used only that way is still a stack:
end = []
front = []
for n in [10, 20, 30]:
end.append(n)
front.insert(0, n)
print(end, front)
print(end.pop(), front.pop(0))
print(end.pop(), front.pop(0))[10, 20, 30] [30, 20, 10] 30 30 20 20
Same items out, in the same order. So the output cannot tell you which end to choose. What does tell you is what happens to all the other items. Push and pop below, and watch the boxes that were not pushed or popped:
One stack, kept two ways. Push and pop, and watch the items that were not pushed or popped.
push: stack.append(x)pop: stack.pop()push: stack.insert(0, x)pop: stack.pop(0)nothing yetSame values, same order — both are correct stacks. The difference is the amber boxes. Six items is nothing, but with 1,000 items in the list, every insert(0, x) shifts all 1,000 along and every pop(0) shifts 999, while append() and pop() still touch no other item.
Working at the end of a list, no other item changes its position. Working at the front, every item has to shift along by one, every time. That is why a list-based stack always uses append() and pop(), and why the end is the top.
6Popping an empty list
stack = [10]
print(stack.pop())
print(stack.pop())10
Traceback (most recent call last):
File "empty_pop.py", line 3, in <module>
print(stack.pop())
^^^^^^^^^^^
IndexError: pop from empty listThe first pop works. The second has nothing to take, and Python stops the program with IndexError. This is the underflow from the last lesson — underflow is the stack word for it, and IndexError is the name Python gives it.
So a program checks first. There are three common ways to ask “is the stack empty?”, and you will see all three in answer keys:
stack = []
print(len(stack) == 0, stack == [], not stack)
stack.append(5)
print(len(stack) == 0, stack == [], not stack)
print(bool([]), bool([5]))True True True False False False False True
The first two are plain comparisons. The third works because an empty list counts as False and a list with anything in it counts as True — the last line shows bool() saying so. That is also why you will see while stack: in some answers. It means “while the stack is not empty”.
len(stack) == 0 says exactly what it means, and it is what the rest of this chapter uses.7A stack is a list with a promise
A list lets you do plenty that a stack must not. Python will not stop you, because it is still a list. Each of these breaks the stack's rule:
stack[0]Reads the bottom item. A stack only lets you see the top.
stack.insert(1, 99)Puts an item in the middle. A push only ever goes on top.
stack.remove(20)Takes out an item from wherever it is. A pop only takes the top.
stack.sort()Rearranges the whole stack. The order of a stack is the order items arrived in.
append(), pop(), [-1] and len(). Anything else is using a list, not a stack.8Try it
9A board question
“Stack is a linear data structure which follows a particular order in which the operations are performed.” What is the order in which the operations are performed in a stack? Name the list method used to remove the last element from a list implemented stack, and write an example using Python statements. (CBSE 2022, Term 2 · 2 marks)
The order is LIFO, Last In First Out. The method is pop(). An example:
stack = [10, 20, 30]
stack.pop()
print(stack)[10, 20]
10Recap
append() adds there, pop() removes there, stack[-1] reads there.
The top is the right-hand end of the printed list.
No other item changes position. At the front, every item shifts.
IndexError: pop from empty list. Check len(stack) == 0 first.
Assertion (A): A stack is a LIFO structure. Reason (R): Any new element pushed into the stack always gets positioned at the index after the last existing element in the stack. (CBSE 2023)
stack = [4, 8, 15]. What does stack[-1] give, and what is stack afterwards?
In a list-based stack, which line pops?
What happens when stack.pop() runs on an empty list?