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
In this specific case it is because list
s 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 tuple
s 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).
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.
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.
nums
are different and they point to a same object or 2 different objects, though they have same name.func1(nums)
, mean that you pass a reference. Now the 2 variable nums
point to same object. (2 variables, 1 object)func1
, the inside variable nums
will point to a new object, the outside is still unchanged (2 variables, 2 object)print nums
then this nums
is the outside variable, There are two reasons for this result:
In func1
,nums
refer to a new object because a new list is created. Therefore global nums
is not affected.
In func2
, the modification is applied to the object passed in. Thus global nums
is changed. A new object is not created because list
is mutable.
ref: https://docs.python.org/3/faq/programming.html#what-are-the-rules-for-local-and-global-variables-in-python