title: Efficient Stack implementation in Python
body: <p><strong>1st Implementation</strong>: The following stack implementation assumes that the end of the list will hold the top element of the stack. As the stack grows, new items will be added on the end of the list.</p>
  
  <pre><code>class Stack:
      def __init__(self):
          self.items = []
  
      def isEmpty(self):
          return self.items == []
  
      def push(self, item):
          self.items.append(item)
  
      def pop(self):
          return self.items.pop()
  
      def peek(self):
          return self.items[len(self.items)-1]
  
      def size(self):
          return len(self.items)
  </code></pre>
  
  <p><strong>2nd Implementation</strong> : The second implementation assumes that the beginning of the list holds the top element of the stack and new items are added at the index 0.</p>
  
  <pre><code> class Stack:
       def __init__(self):
           self.items = []
  
       def isEmpty(self):
           return self.items == []
  
       def push(self, item):
           self.items.insert(0,item)
  
       def pop(self):
           return self.items.pop(0)
  
       def peek(self):
           return self.items[0]
  
       def size(self):
           return len(self.items)
  </code></pre>
  
  <p>Being a beginner to Data Structures, I would like to know:<br>
  1. Which implementation is more efficient with respect to time or space, and why ?<br>
  2. Is the time complexity of the <code>insert(0)</code> in the 2nd implementation O(n). If yes, how ? </p>