user2540878
user2540878

Reputation: 9

One of my lists shouldn't change, but it does

So I have a function:

def flip_stack(stack, nFlip):
    """flip_stack(list, num)
    Edits stack to flip the first nFlip elements in the stack."""
    newStack = stack[:nFlip]
    for element in newStack:
        stack.remove(element)
    newStack.reverse()
    stack = newStack + stack
    return(stack)

Given

stack = [2, 3, 1, 4, 0]
nFlip = 3
stack = [1, 3, 2, 4, 0]

This much of it works. It flips the stack at the correct place.

However, when I use that later:

difStack = stack
flip_pancakes(difStack, difStack.index(max(difStack)) + 1) # flip stack so largest number is at front
print(stack)

stack suddenly becomes [0] Does anyone know why? The flip_pancakes() function in the second bit of code should have only changed difStack, right?

And I realize that that that particular bit is really messy; any way to improve that?

Thanks!

Upvotes: 0

Views: 63

Answers (3)

Blckknght
Blckknght

Reputation: 104712

The other answers have correctly identified the issue, that you're modifying the list that gets passed into the function. However, I think their suggested solution is not ideal.

Instead of copying part of the list, then looping to remove some of the values, just do a pair of slices and concatenate:

def flip_stack(stack, nFlip):
    return stack[nFlip-1::-1] + stack[nFlip:]

This does not modify stack at all. The first slice has a negative "step" term, so it reverses the order of the values.

If you did want the flipping to happen in place, rather than creating a new list for the new ordering, You could do a slice assignment, rather than forming a new list by concatenating two slices. Here's how I'd do that:

def flip_stack_inplace(stack, nFlip):
    stack[:nFlip] = stack[nFlip-1::-1]

This version doesn't explicitly return anything (which means it really returns None, since that's Python's default return value). All of the changes are done directly within the stack list.

Example usage:

>>> s = [1, 2, 3, 4, 5]
>>> print(flip_stack(s, 3))
[3, 2, 1, 4, 5]
>>> print(s)
[1, 2, 3, 4, 5]
>>> flip_stack_inplace(s, 3)
>>> print(s)
[3, 2, 1, 4, 5]

Upvotes: 1

Raymond Hettinger
Raymond Hettinger

Reputation: 226296

The difstack list isn't a new list.

Change this:

difStack = stack

To this:

 difStack = stack[:]

Upvotes: 1

Blender
Blender

Reputation: 298166

difStack = stack doesn't clone stack. Both of those variables still point to the same list object.

If you want to clone a list, slice it:

difStack = stack[:]

Or pass it into the list() builtin:

difStack = list(stack)

Upvotes: 0

Related Questions