Search code examples
pythonoopiteratorstack

Creating a stack and iterator that runs thorugh the stack using a for loop


I'm trying to create a stack with the LIFO principal. I am able to do this using just the push and pop function. But I want to create a iter and a next function to traverse through the stack. Below is what I have tried, but can't really figure out the logic.

class Stack:
  def __init__(self):
     self.stack = []
     self.START = None
     self.END = None

def push(self, item):
    self.stack.append(item)
    #print("item added to stack")

def pop(self):
    return self.stack.pop()
    #print("value removed according to LIFO")

def emptystack(self):
    return len(self.stack) == 0

def __iter__(self):
    self.Iterator = self.START
    return self

def __next__(self):
    if self.Iterator != None:
        stack = self.Iterator
        self.Iterator = self.Iterator.NEXT
        return node
    else:
        raise StopIteration


def fullstack(self):
    return self.stack

s = Stack()
s.push('1')
s.push('2')
s.push('6')
s.push('8')
s.push('11')
s.push('12')
s.pop()
s.push('50')
if s.emptystack():
   print("Stack is empty")
else:
   print(s.fullstack())

Solution

  • Your Iterator attribute will always be None, because you stop the iteration as soon as the first call to next happens. Think of next as being called for every item until there's no more items to process, from the Python documentation about __next__:

    Return the next item from the container. If there are no further items, raise the StopIteration exception

    One thing you could do is initialize the self.Iterator to the stack's length (in __iter__), then on every step, decrement it until you reach 0 (and then raise StopIteration):

    def __iter__(self):
        self.Iterator = len(self.stack) - 1  # initialize to the index of the last element
        return self
    
    def __next__(self):
        if self.Iterator >= 0:
            current_value = self.stack[self.Iterator]
            self.Iterator = self.Iterator - 1  # update for the next step
            return current_value
        else: # stop if self.Iterator is -1
            raise StopIteration