Ещё одной полезной коллекцией является стек реализующий принцип «Последний пришёл – первый ушёл». Его часто представляют как стопку карт или магазин пистолета, где приходящие элементы закрывают выход уже находящимся в коллекции.
Реализуйте класс Stack, который не имеет параметров инициализации, но поддерживает методы:
- push(item)— добавить элемент в конец стека;
- pop()— «вытащить» первый элемент из стека;
- is_empty()— проверяет стек на пустоту.
Примечание
Ваше решение должно содержать только классы и функции.
В решении не должно быть вызовов инициализации требуемых классов.
Пример
Ввод
stack = Stack()
for item in range(10):
    stack.push(item)
while not stack.is_empty():
    print(stack.pop(), end=" ")Вывод
9 8 7 6 5 4 3 2 1 0 Ввод
stack = Stack()
for item in ("Hello,", "world!"):
    stack.push(item)
while not stack.is_empty():
    print(stack.pop())Вывод
world!
Hello,Решение
Эта задача отличается от предыдущей только тем, что метод pop() удаляет не первый, а последний элемент нашего списка. Поэтому я не буду приводить три варианта, а ограничусь только двумя. За описанием процесса я тоже отправлю к предыдущей задаче. Разница минимальна. Стоит только отметить, что структура Node диктует нам «обратный» порядок присоединения новых элементов в стек. Код написан так, будто мы добавляем элемент в начало списка и удаляем так же элемент из начала списка. 
Чтобы понять разницу между стеком и очередью и почему так происходит, можно попробовать представить себе  книги. Когда мы говорим об очереди, книги стоят на полке и мы всегда добавляем новые с правой стороны, а забираем с левой. В случае стека книги лежат стопкой и мы не можем взять книгу, которую положили первой — для этого нам надо снять все книги, которые мы положили раньше в обратном порядке. Поэтому с точки зрения банальной эрудиции самый последний добавленный элемент всегда будет самым первым. По сути же мы можем назвать нашу переменную previous вместо next и тогда все встанет на свои места. Мы начнем забирать элементы «с конца».
Так же стоит обратить внимание, что в случае стека, мы обходимся только одной перменной, указываюшей на текущий элемент.
Посмотреть код
Решение
# решение, базирующееся на встроенных списках
class Stack:
    def __init__(self) -> None:
        self.stack = []
    def push(self, item):
        self.stack.append(item)
    def pop(self):
        return self.stack.pop()
    def is_empty(self):
        return self.stack == []Решение
# классическое решение без испольщовнаия встроенных списков.
class Node:
    def __init__(self, item) -> None:
        self.item = item
        self.next = None
class Stack:
    def __init__(self) -> None:
        self.head = None
    def push(self, item):
        if self.is_empty():
            self.head = Node(item)
        else:
            new_node = Node(item)
            new_node.next = self.head
            self.head = new_node
    def pop(self):
        if self.is_empty():
            return None
        item = self.head.item
        self.head = self.head.next
        return item
    def is_empty(self):
        return self.head is None