Python: Modify Global list inside a function

14,644

Solution 1

I understand that I can use global statement to access global variables

Your understanding is wrong. You can always access a global variable as long as you don't have a local variable of the same name. You only need the global statement when you are going to change what object a variable name refers to. In your func2, you are not doing that; you are only changing the contents of the object. nums still refers to the same list.

Solution 2

It is of concept based on mutable and immutable objects in Python. In your case, for example:

a=[1,2]
def myfn():
    a=[3,4]
    print id(a)

>>>id(a)
3065250924L
>>>myfn()
3055359596

It is clear both are different objects. Now:

a=[1,2]
def myfn():
    a[:] =[3,4]
    print id(a)

>>>id(a)
3055358572
>>>myfn()
3055358572

That means it is same variable using in local and global scope.

Solution 3

In this specific case it is because lists are mutable.

As a result having them in the global namespace, or even passed through a function, means that they will be changed as Python holds the reference to the mutable object, not a copy of it.

If you try the same thing with tuples it will not work, as they are immutable.

The way to avoid this is to provide a copy of the list to the function, not the list itself:

func2(list[:])

At the same time you can do this with default arguments, where you can specify a default argument to be [], and if you then .append() something to it, that default argument will forever hold that item within it for all future calls (unless you remove it in some way).

Share:
14,644

Related videos on Youtube

Yuhao Zhang
Author by

Yuhao Zhang

Updated on September 16, 2022

Comments

  • Yuhao Zhang
    Yuhao Zhang over 1 year

    First of all, I understand that I can use global statement to access global variables. But somehow I was able to modify a global list without global like below:

    def func1(nums):
        nums = [4,5,6]
    
    nums = [1,2,3]
    func1(nums)
    print nums # print [1,2,3]
    
    def func2(nums):
        nums[0] = 4
        nums[1] = 5
        nums[2] = 6
    
    nums = [1,2,3]
    func2(nums)
    print nums # print [4,5,6]
    

    After trying func2, I realized that I can always access global list in a function if I specify the index:

    def func3(nums):
        nums[:] = [4,5,6]
    
    nums = [1,2,3]
    func3(nums)
    print nums # print [4,5,6]
    

    Is it because Python automatically go trying to match a global variable if a function variable is used before definition?

  • Aran-Fey
    Aran-Fey over 5 years
    That has nothing to do with mutability. It's a matter of mutating a value vs rebinding the value of a variable.