Confused about the scope of variable in python

Question:

I was studying merge sort and I wrote this code

def mergesort(a): #sorting algo
    #code is alright just confused about scope of variable
    if(len(a)>1):
        mid = len(a)//2
        l = a[:mid]
        r = a[mid:]
        mergesort(l)
        mergesort(r)
        i=j=k=0
        while(i<len(l) and j<len(r)):
            if(l[i]>r[j]):
                a[k] = r[j]
                j+=1
            else:
                a[k] = l[i]
                i+=1
            k+=1
        
        while(i<len(l)):
            a[k] = l[i]
            i+=1
            k+=1

        while(j<len(r)):
            a[k] = r[j]
            j+=1
            k+=1        

a = [30,2,4,5,-1,3,7,3,9,2,5]
mergesort(a)
print(a)

here a is an global variable, but when the function parameter name is also a doesn’t the a in function scope override the a in global scope? how the global variable is getting edited inside mergesort function?

I tried another code with same approach but here the global variable doesn’t get edited(as expected),how is this different from the above code?

def foo(a):
    a=20

a = 10
foo(a)
print(a)
Asked By: Manoj D Bhat

||

Answers:

The problem is not that a is global (because it’s not). The a is local to the function, but it references the same list as the global a (because variables are passed by reference in python).

a is a list (which is mutable) in the first example, while a is an integer (which is immutable) in the second example. So changing values inside of the list (like a[k] = l[i]), changes the global list as well, while changing the reference to an integer (like a = 20) only replaces the local reference.

If you don’t want the function to change the global list, you can fix it by creating a copy of the list:

def mergesort(a):
    a = a[:] # or a = a.copy(), whichever you prefer
    ...

Note that in this case, the function has no effect, so you’d probably want to return the resulting list.

Answered By: Yevhen Kuzmovych

Lists are mutable but int is not. So when you change int, you get an entirely new int. When you make changes within a list, you don’t get a new list. You just have a modified list.

So when you pass the list to a function, it does not create a new list unless you do something like this: a.copy() or a[:] which creates a new list. In your case, you are using the same list as outside the function.

For more info read about mutability of data types or pass by reference and pass by value.

Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.