1

Code:

class Stack:
    def __init__(self):
        self.items = []

    def is_empty(self):
        return self.items == []

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

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

def length(stack):
    i = 0
    while not stack.is_empty():
        stack.pop()
        i += 1
    return i

s1 = Stack()
s1.push(3)
s1.push(2)
s1.push(1)
print(length(s1))
s1.pop()

Output:

3
Traceback (most recent call last):
  File "Stack.py", line 26, in <module>
    s1.pop()
  File "Stack.py", line 12, in pop
    return self.items.pop()
IndexError: pop from empty list

I want the function length() to be able to modify a copy of s1 instead on changing s1. Is there any way to do this in python?

I am not allowed to directly use s1.items so I can't just use s1[:]. I can't modify the class either.

MSeifert
  • 145,886
  • 38
  • 333
  • 352
Shoeboom
  • 88
  • 1
  • 6
  • Possible duplicate of [python list by value not by reference](https://stackoverflow.com/questions/8744113/python-list-by-value-not-by-reference) – Nadeem Jun 03 '17 at 14:20
  • @MohammadNadeem Not really because the question states that accessing the `items` isn't possible (or allowed). – MSeifert Jun 03 '17 at 14:21

1 Answers1

2

You could simply use the copy module:

import copy

# ... your code ...

print(length(copy.deepcopy(s1)))  # pass a copy to the length function

Or if you want it without extra module and if you can alter the length function you could simply keep the popped items and push them again after you have the length:

def length(stack):
    i = 0
    tmp = []
    while not stack.is_empty():
        tmp.append(stack.pop())    # append them to your temporary storage
        i += 1
    for item in tmp:               # take the items saved in the temporary list
        stack.push(item)           # and push them into your stack again
    return i
MSeifert
  • 145,886
  • 38
  • 333
  • 352