0

I have 2 example below, and my question is: why List L don't need global to change value like variable V, I think, more Safe if L need global to change

Example 1:

L=[1,2,3,4]  
V=5          
def U():
    L[1]=22
    V=55
U()
print L[1]
print V

Result 1:

22
5

Example 2:

L=[1,2,3,4]  
V=5          
def U():
    L[1]=22  
    global V   #Now V will change like L[1]
    V=55
U()
print L[1]
print V

Result 2:

22
55
pc43
  • 439
  • 1
  • 7
  • 19
  • 1
    Because lists are mutable but integers are immutable... See e.g. http://stackoverflow.com/q/27795943/3001761 – jonrsharpe May 12 '15 at 22:25
  • 1
    See also http://nedbatchelder.com/text/names.html, which is a useful introduction to identifiers in Python. You *would* need `global` to reassign `L` to a completely different object, just not to mutate the object it already references. – jonrsharpe May 12 '15 at 22:31

1 Answers1

1

Perhaps someone can explain it better than me, but when you do the following:

print V

Python knows this variable isn't defined in your functions scope, and so it checks the global scope, and prints it.

If you were to do instead

V=5

Python knows this variable isn't defined in your functions scope, so it goes ahead and creates it (now it over-shadows V at the global scope). There is different behaviour between writing a variable and reading it.

Now compare this to a list:

L[1]=22

This is similar to print V. Why? Because Python needs to find where L is defined in memory, and then modifies its second index. This is a read followed by a write, whereas print V is simply a read from memory.

When your operation needs to do a read first, it will find the reference that was defined at the outer scope, and that is why you see a difference between V=55 and L[1]=22.

When your operation is a write first, it will create a new variable in the function scope unless you have that variable marked as a global. Then it will modify that global instead.

Martin Konecny
  • 57,827
  • 19
  • 139
  • 159
  • 1
    This isn't quite correct. `L[1] = 22` doesn't *"de-reference"* `L`, just the object that was previously referenced via `L[1]` (strictly, it decrements the object's reference count). It doesn't *"modify its data structure"* either, as such, it just puts a different reference into the appropriate slot (and increments the relevant reference count for the new object). – jonrsharpe May 12 '15 at 22:33
  • Reworded the answer. – Martin Konecny May 12 '15 at 22:43