Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python: Modify Global list inside a function

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?

like image 409
Yuhao Zhang Avatar asked Jul 15 '15 16:07

Yuhao Zhang


People also ask

How do you change a global list in a function in Python?

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.

Can you modify a list in a function Python?

Because lists and dictionaries are mutable, changing them (even inside a function) changes the list or dictionary itself, which isn't the case for immutable data types.

Can you use global variables in a function Python?

In other words, variables that are declared outside of a function are known as global variables. You can access global variables in Python both inside and outside the function.


3 Answers

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.

like image 135
kindall Avatar answered Sep 21 '22 02:09

kindall


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.

like image 20
itzMEonTV Avatar answered Sep 24 '22 02:09

itzMEonTV


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).

like image 22
NDevox Avatar answered Sep 21 '22 02:09

NDevox