Arhn - архитектура программирования

Реализация стека с помощью Python

Я пытаюсь реализовать простой стек с Python, используя массивы. Мне было интересно, может ли кто-нибудь сообщить мне, что не так с моим кодом.

class myStack:
     def __init__(self):
         self = []

     def isEmpty(self):
         return self == []

     def push(self, item):
         self.append(item)

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

     def size(self):
         return len(self)

    s = myStack()
    s.push('1')
    s.push('2')
    print(s.pop())
    print s


Ответы:


1

Я исправил несколько проблем ниже. Кроме того, «стек», в терминах абстрактного программирования, обычно представляет собой набор, в который вы добавляете и удаляете сверху, но то, как вы его реализовали, вы добавляете сверху и удаляете снизу, что делает его очередью .

class myStack:
     def __init__(self):
         self.container = []  # You don't want to assign [] to self - when you do that, you're just assigning to a new local variable called `self`.  You want your stack to *have* a list, not *be* a list.

     def isEmpty(self):
         return self.size() == 0   # While there's nothing wrong with self.container == [], there is a builtin function for that purpose, so we may as well use it.  And while we're at it, it's often nice to use your own internal functions, so behavior is more consistent.

     def push(self, item):
         self.container.append(item)  # appending to the *container*, not the instance itself.

     def pop(self):
         return self.container.pop()  # pop from the container, this was fixed from the old version which was wrong

     def peek(self):
         if self.isEmpty():
             raise Exception("Stack empty!")
         return self.container[-1]  # View element at top of the stack

     def size(self):
         return len(self.container)  # length of the container

     def show(self):
         return self.container  # display the entire stack as list


s = myStack()
s.push('1')
s.push('2')
print(s.pop())
print(s.show())
16.08.2013
  • Спасибо за помощь. 16.08.2013
  • Чтобы сделать это стеком, функция pop должна быть def pop(self): return self.container.pop(-1) 08.08.2014
  • @Санджу или просто self.container.pop(). 06.05.2015
  • почему последний вывод объекта ‹__main__.myStack по адресу 0x006C39D0›? 16.12.2016
  • AttributeError: объект «Стек» не имеет атрибута «стек».. проверьте свою функцию show(self) 05.09.2018
  • self.size() не работает. Это должно быть либо self.container == [], либо len(self.container) == 0 01.01.2021
  • @EnisArik Работает для меня - какую ошибку или неожиданное поведение вы получаете? 01.01.2021
  • @Бриониус, ах, это моя беда! Я не включил метод size :) В этом была проблема. 01.01.2021

  • 2

    Присвоение self не превратит ваш объект в список (а если бы это произошло, у объекта больше не было бы всех ваших методов стека). Присвоение self просто изменяет локальную переменную. Вместо этого установите атрибут:

    def __init__(self):
        self.stack = []
    

    и используйте атрибут вместо простого self:

    def push(self, item):
        self.stack.append(item)
    

    Кроме того, если вам нужен стек, вам нужен pop(), а не pop(0). pop(0) превратит вашу структуру данных в (n неэффективную) очередь.

    16.08.2013

    3

    Я оставил комментарий со ссылкой на http://docs.python.org/2/tutorial/datastructures.html#using-lists-as-stacks, но если вы хотите иметь собственный тип, который предоставляет вам удобные методы push, pop, is_empty и size, я d просто подкласс list.

    class Stack(list):
        def push(self, item):
            self.append(item)
        def size(self):
            return len(self)
        def is_empty(self):
            return not self
    

    Однако, как я сказал в комментариях, я бы, вероятно, просто придерживался здесь прямой list, так как все, что вы на самом деле делаете, — это псевдонимы существующих методов, которые обычно служат только для того, чтобы ваш код было труднее использовать в долгосрочной перспективе, поскольку он требует, чтобы люди, использующие его, изучали ваш псевдоним интерфейса поверх оригинала.

    16.08.2013
  • is_empty должен вернуть not self. Конечно, делать это вообще — плохая идея; он пытается сделать интерфейсы коллекций Python похожими на какой-то другой язык. 16.08.2013
  • Моя ошибка насчет is_empty, я ее исправил. Что касается вашего другого момента, я согласен с тем, что в этом случае вам, вероятно, следует просто использовать стандартный интерфейс списка, но создание подкласса для реализации дополнительного интерфейса в существующем типе вполне разумно, если у вас есть законная потребность. 16.08.2013
  • как бы вы определили поп? pop(я, предмет): self.pop(предмет)? 16.08.2013
  • Вам это не нужно, потому что у list уже есть pop, который работает именно так, как вам нужно, без каких-либо аргументов. 16.08.2013
  • Однако вам действительно следует просто использовать интерфейс list напрямую, если только вам не нужны псевдонимы имен методов для какого-либо домашнего задания. 16.08.2013
  • Это то, что я тоже чувствовал. Все, что делает код, уже доступно в виде методов в списке в python. Более подробная информация о том, как использовать список в качестве стека, доступна в документации docs.python.org/3/tutorial/datastructures.html 02.06.2018

  • 4

    Правильная реализация также будет включать __iter__, поскольку стек должен быть в порядке LIFO.

    class Stack:
        def __init__(self):
            self._a = []
    
        def push(self, item):
            self._a.append(item)
    
        def pop(self):
            return self._a.pop()
    
        def isEmpty(self):
            return len(self._a) == 0
    
        def __iter__(self):
            return reversed(self._a)
    
        def __str__(self):
            # return str(list(reversed(self._a)))
            return str(list(iter(self)))
    
    def main():
        stack = Stack()
        stack.push('a')
        stack.push('b')
        stack.push('c')
        stack.pop()
        print(stack)
        if stack:
            print("stack not empty")
        stack.pop()
        stack.pop()
        if stack.isEmpty():
            print("stack empty")
    
    if __name__ == '__main__':
        main()
    
    19.06.2017

    5

    Стек — это контейнер (линейная коллекция), в котором операции с динамическими множествами выполняются по принципу «последний пришел — первый ушел» (LIFO). Есть только один указатель — top, который и используется для выполнения этих операций.

    Реализация стека CLRS с использованием массива:

    class Stack:
        """
        Last in first out (LIFO) stack implemented using array.
        """
        def __init__(self, capacity=4):
            """
            Initialize an empty stack array with default capacity of 4.
            """
            self.data = [None] * capacity
            self.capacity = capacity
            self.top  = -1
    
        def is_empty(self):
            """
            Return true if the size of stack is zero.
            """
            if self.top == -1:
                return True
            return False
    
        def push(self, element):
            """
            Add element to the top.
            """
            self.top += 1
            if self.top >= self.capacity:
                raise IndexError('Stack overflow!')
            else:
                self.data[self.top] = element
    
        def pop(self):
            """
            Return and remove element from the top.
            """
            if self.is_empty():
                raise Exception('Stack underflow!')
            else:
                stack_top = self.data[self.top]
                self.top -= 1
                return stack_top
    
        def peek(self):
            """
            Return element at the top.
            """
            if self.is_empty():
                raise Exception('Stack is empty.')
                return None
            return self.data[self.top]
    
        def size(self):
            """
            Return the number of items present.
            """
            return self.top + 1
    
    

    Тестирование реализации:

    def main():
        """
        Sanity test
        """
        stack = Stack()
    
        print('Size of the stack is:', stack.size())
        stack.push(3)
        print('Element at the top of the stack is: ', stack.peek())
        stack.push(901)
        print('Element at the top of the stack is: ', stack.peek())
        stack.push(43)
        print('Element at the top of the stack is: ', stack.peek())
        print('Size of the stack is:', stack.size())
        stack.push(89)
        print('Element at the top of the stack is: ', stack.peek())
        print('Size of the stack is:', stack.size())
        #stack.push(9)    # Raises IndexError
        stack.pop()
        print('Size of the stack is:', stack.size())
        stack.pop()
        print('Size of the stack is:', stack.size())
        stack.pop()
        print('Size of the stack is:', stack.size())
        print('Element at the top of the stack is: ', stack.peek())
        stack.pop()
        #print('Element at the top of the stack is: ', stack.peek())    # Raises empty stack exception
    
    if __name__ == '__main__':
        main()
    
    30.10.2020

    6

    Ваша проблема в том, что вы выскакиваете из начала списка, когда вы должны выскакивать из конца списка. Стек — это структура данных «последний пришел — первый вышел». Это означает, что когда вы что-то выталкиваете из него, это что-то будет тем, что вы вставили последним. Взгляните на свою функцию push — она добавляет элемент в список. Это означает, что он идет в конце списка. Однако когда вы вызываете .pop(0), вы удаляете первый элемент в списке, а не тот, который вы добавили последним. Удаление 0 из .pop(0) должно решить вашу проблему.

    16.08.2013
  • Это не главная проблема. Большая проблема заключается в попытке назначить self. 16.08.2013
  • Спасибо за помощь. 16.08.2013

  • 7

    Ваш стек представляет собой массив...

    class stacked(): # Nodes in the stack
        def __init__(self,obj,next):
            self.obj = obj
            self.next = next
        def getObj(self):
            return(self.obj)
        def getNext(self):
            return(self.next)
    
    class stack(): # The stack itself
        def __init__(self):
            self.top=None
        def push(self,obj):
            self.top = stacked(obj,self.top)
        def pop(self):
            if(self.top == None):
                return(None)
            r = self.top.getObj()
            self.top = self.top.getNext()
            return(r)
    
    29.03.2015

    8

    Ниже приведена простая реализация стека в python. Кроме того, он возвращает средний элемент в любой момент времени.

      class Stack:
            def __init__(self):
                self.arrList = []
    
            def isEmpty(self):
                if len(self.arrList):
                    return False
                else:
                    return True
    
            def push(self, val):
                self.arrList.append(val)
    
            def pop(self):
                if not self.isEmpty():
                    self.arrList[len(self.arrList)-1]
                    self.arrList = self.arrList[:len(self.arrList)-1]
                else:
                    print "Stack is empty"
    
            def returnMiddle(self):
                if not self.isEmpty():
                    mid = len(self.arrList)/2
                    return self.arrList[mid]
                else:
                    print "Stack is empty"
    
            def listStack(self):
                print self.arrList
    
        s = Stack()
        s.push(5)
        s.push(6)
        s.listStack()
        print s.returnMiddle()
        s.pop()
        s.listStack()
        s.push(20)
        s.push(45)
        s.push(435)
        s.push(35)
        s.listStack()
        print s.returnMiddle()
        s.pop()
        s.listStack()
    

    Выход:

    [5, 6]
    6
    [5]
    [5, 20, 45, 435, 35]
    45
    [5, 20, 45, 435]
    
    28.08.2016

    9

    Реализация стека в Python из книги "Решение проблем с помощью алгоритмов и Структуры данных

    06.11.2016

    10

    Ниже моя реализация

    class Stack:
        def __init__(self):
            self.items = list()
        def is_empty(self):
            return self.items == []
        def peek(self):
            if self.is_empty():
                print('Cannot peek empty stack')
                return
            else:
                return self.items[-1]
        def pop(self):
            if self.is_empty():
                print('Cannot pop an empty stack')
                return
            else:
                return self.items.pop()
        def size(self):
            return len(self.items)
        def push(self,data):
            self.items.append(data)
    
    07.12.2018

    11

    Я хотел бы поделиться своей версией реализации стека, которая наследует список Python. Я считаю, что итерация в стеке должна происходить в порядке LIFO. Кроме того, должна быть предусмотрена итерация pop-all() для итерации при извлечении всех элементов. Я также добавил stack.clear() для очистки стека (как в deque.clear() в модуле коллекций). Я также переопределил __repr__ для целей отладки:

    class Stack(list):
    
        def push(self, item):
            self.append(item)
    
        def top(self):
            return self[-1]
    
        def size(self):
            return len(self)
    
        def isempty(self):
            return self.size() == 0
    
        def __iter__(self):
            """ iter in lifo """
            return super(Stack, self).__reversed__()
    
        def __reversed__(self):
            return super(Stack, self).__iter__()
    
        def popall(self):
            try:
                while True:
                    yield self.pop()
            except IndexError:
                pass
    
        def clear(self):
            del self[:]
    
        def __repr__(self):
            if not self:
                return '%s()' % self.__class__.__name__
            return '%s(%s)' % (self.__class__.__name__, super(Stack, self).__repr__())
    

    Вот как вы можете его использовать:

    stack = Stack(range(5))
    print "stack: ", stack  # stack:  Stack([0, 1, 2, 3, 4])
    
    print "stack.pop() => ", stack.pop() # stack.pop() =>  4
    print "stack.push(20) " # stack.push(20) 
    stack.push(20)
    for item in stack:
        print item  # prints 20, 3, 2... in newline
    print "stack: ", stack # stack:  Stack([0, 1, 2, 3, 20])
    print "stack pop all..."
    for item in stack.popall(): # side effect to clear stack
        print item
    print "stack: ", stack # stack:  Stack()
    

    Прежде всего, я реализовал его для решения проблемы программирования следующий больший элемент< /а>.

    03.05.2019
    Новые материалы

    Коллекции публикаций по глубокому обучению
    Последние пару месяцев я создавал коллекции последних академических публикаций по различным подполям глубокого обучения в моем блоге https://amundtveit.com - эта публикация дает обзор 25..

    Представляем: Pepita
    Фреймворк JavaScript с открытым исходным кодом Я знаю, что недостатка в фреймворках JavaScript нет. Но я просто не мог остановиться. Я хотел написать что-то сам, со своими собственными..

    Советы по коду Laravel #2
    1-) Найти // You can specify the columns you need // in when you use the find method on a model User::find(‘id’, [‘email’,’name’]); // You can increment or decrement // a field in..

    Работа с временными рядами спутниковых изображений, часть 3 (аналитика данных)
    Анализ временных рядов спутниковых изображений для данных наблюдений за большой Землей (arXiv) Автор: Рольф Симоэс , Жильберто Камара , Жильберто Кейрос , Фелипе Соуза , Педро Р. Андраде ,..

    3 способа решить квадратное уравнение (3-й мой любимый) -
    1. Методом факторизации — 2. Используя квадратичную формулу — 3. Заполнив квадрат — Давайте поймем это, решив это простое уравнение: Мы пытаемся сделать LHS,..

    Создание VR-миров с A-Frame
    Виртуальная реальность (и дополненная реальность) стали главными модными терминами в образовательных технологиях. С недорогими VR-гарнитурами, такими как Google Cardboard , и использованием..

    Демистификация рекурсии
    КОДЕКС Демистификация рекурсии Упрощенная концепция ошеломляющей О чем весь этот шум? Рекурсия, кажется, единственная тема, от которой у каждого начинающего студента-информатика..