thisArray
is re-assigned to a new list object by slicing, so any changes after that don't affect the original list passed into the function. Note the instance IDs of the lists:
def reverse_this(thisArray):
saved_first = thisArray[0]
print(f'thisArray pre-slice: {id(thisArray):#x}')
thisArray = thisArray[1:]
print(f'thisArray post-slice: {id(thisArray):#x}')
thisArray.reverse()
thisArray.insert(0,saved_first)
myList = ['foo', 1,2,3,4,5]
print(f'myList pre-call: {id(myList):#x}')
reverse_this(myList)
print(f'myList post-call: {id(myList):#x}')
print('after:', myList)
myList pre-call: 0x1e2f5713500
thisArray pre-slice: 0x1e2f5713500 # parameter refers to original list
thisArray post-slice: 0x1e2f5753800 # thisArray refers to new list
myList post-call: 0x1e2f5713500 # original list isn't changed.
after: ['foo', 1, 2, 3, 4, 5]
In Python, variables are names of objects. If you mutate an object, all names of that object "see" the change. A slice makes a new object, and in this case the name was reassigned to the new object.
To fix it, assign the slice into the full range of the original list, which mutates the original list instead of creating a new one:
def reverse_this(thisArray):
saved_first = thisArray[0]
thisArray[:] = thisArray[1:] # replace entire content of original list with slice.
thisArray.reverse() # thisArray still refers to original list here.
thisArray.insert(0,saved_first)
myList = ['foo', 1,2,3,4,5]
reverse_this(myList)
print('after:', myList)
after: ['foo', 5, 4, 3, 2, 1]
When assigning to a slice, a section of a list is replaced in place with another list. It doesn't necessarily have to be the same size.
Another example:
>>> s = list(range(10))
>>> s
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> id(s)
2339680033664
>>> s[4:7] = [10,10] # replace indices 4 up to but not including 7
>>> s
[0, 1, 2, 3, 10, 10, 7, 8, 9]
>>> id(s) # id didn't change
2339680033664