0

I'm confused by the following example. Let a=[1] be a python list and try to write a function which re-assigns the list such that we will have a=[2] after running the function.

A simple function which works is

def works1(arr):
    arr[0]=2

or another example is

def works2(arr):
    arr[0]=2*arr[0]

Either does what I would want when running works1(a) or works2(a): both set a=[2].

However, something like the following which tries to re-assign the entire array at once, rather than doing it component-by-component, will fail.

def fails1(arr):
    arr=[2*x for x in arr]

Running fails1(a) does not reassign a, which is still given by a=[1].

Could someone please explain this behavior or point me to where in the documentation I should be looking to understand the above?

Edit: For context, if helpful, I was trying to understand why the mergeSort code at this site was able to re-assign an externally defined list. Initially thought that alist within that mergeSort code should be a local variable.

5
  • 3
    arr is a local variable. When you assign it, it no longer contains a reference to the original list. Commented Feb 4, 2021 at 19:32
  • 1
    You can use slice assignment to update the list: arr[:] = [2*x for x in arr] Commented Feb 4, 2021 at 19:32
  • 1
    Also a != arr. a[0] just mutates state on an object, completely different from a reassignment that takes a and points it to an entirely different, newly allocated list. The original variable in the calling scope won't be affected by such a reassignment. Commented Feb 4, 2021 at 19:32
  • Ah sorry I had a typo in both works1 and works2: the previous a instances should have been arr's. But @Barmar, yes exactly, I was actually confused why the works1 and works2 functions accomplish what I want at all, since I thought they'd just be assigning values to a local variable. I see now that since I did not actually initialize what arr is in either of these cases, they cannot be making a new local variable named arr, unlike fails1. Commented Feb 4, 2021 at 19:44
  • @ggorlen thanks, that was just a typo on my part. Should have had arr's where there were a's in works1 and works2. But I think I understand now: could you tell me if my comment above is correct? Commented Feb 4, 2021 at 19:46

1 Answer 1

1

arr is a reference to a list object

When you write arr[0]=1 you change the element in this referenced object. But when you write arr=[..new list..] you just make arr refer to a new object, and it does not affect previous object.

Sign up to request clarification or add additional context in comments.

1 Comment

Cool, yeah that's what I came to understand from the comments above, thanks. I was thought initially that having arr[0]=1 within a function also would initialize arr as a local variable, but I see that is incorrect now.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.