Python Forum
Why doesn't list require global keyword?
Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Why doesn't list require global keyword?
#1
Why doesn't appending to a global list require the global keyword, but modifying a scalar variable does?

numbers = []
dog = 5

def enter_number(x):
	numbers.append(x)

	global dog
	dog += 1

enter_number(1)
enter_number(5)
enter_number(9)
Reply
#2
(Jan-15-2024, 12:02 AM)johnywhy Wrote: Why doesn't appending to a global list require the global keyword, but modifying a scalar variable does?

numbers = []
dog = 5

def enter_number(x):
	numbers.append(x)

	global dog
	dog += 1

enter_number(1)
enter_number(5)
enter_number(9)
You need to understand the scheme of how variables pass to to functions and which ones are mutable and which ones aren't and also scope. In python primitive variables are immutable. What that means is, if you say x = 101 you cannot modify 0 and make it, lets say 1 to make 111. You have assign a new value to the variable which will overwrite existing one.
Lists, on the other hand are mutable objects, as well as dictionaries and classes and some other things. So if you have a list of [0,1,2], you can just go ahead and change a 0 in the list to some other value.

Now, about functions. Since everything in python is an object, python passes references to variables by value to functions. Here is also where scoping rules come into play. If you pass an integer to a function, you can read it. However, when you say x = 5 inside a method, you are creating a new memory location with a local variable x and not modifying one outside of function. This why you need to use global keyword so that python will look up variable in the global scope.

Since lists are mutable, instead of creating a new value, you deference the list and directly modify it in the memory location it was created. However, if you actually do something like numbers = ['x'], it will create a local variable and won't modify the numbers in the outer scope.

Basically when you try to read a variable inside a method, python will first check local scope and then each outer scope until it either finds a variable or throws an error. If you try to write to a variable (assign), it will create one in local scope unless you specify that the variable is in the outer scope.
johnywhy likes this post
Reply
#3
This does assignment.
 dog += 1
This does not:
numbers.append(x)
"global" only affects assignment.

Normally when you assign a value to a variable, it looks for the variable in the local scope. If the variable does not exist, one is created.
Declaring a variable as global tells python to look for the variable in the global scope instead of local scope. If the variable does not exist, one is created in the global scope.

appending a value to a list modifies an existing object, it does not assign a list object to a variable. This code does assignment with a list and requires a global declaration.
def enter_number(x):
global numbers
numbers = [x]
Reply
#4
(Jan-15-2024, 12:34 AM)sgrey Wrote: if you say x = 101 you cannot modify 0

Unclear. x is mutable. I can say
x+=1
Reply
#5
(Jan-15-2024, 01:35 AM)johnywhy Wrote:
(Jan-15-2024, 12:34 AM)sgrey Wrote: if you say x = 101 you cannot modify 0

Unclear. x is mutable. I can say
x+=1
no, what this does is x = x + 1. You are assigning a new value to the variable that overwrites the old one. You cannot change the value that is already assigned to x, you can only assign a new value to it.

Think about it this way: x is a variable, you can change x to anything you want. But the contents of what that variable holds are a different story. You can easier see this with strings.
Say you have s = 'john'. You want to modify it so that the first letter is capital. If it was mutable, you would be able to say s[0] = 'J', and that would work. But you cannot do that because strings are immutable. You can call s[0] and get a 'j' in return, but you cannot assign a new value to it. You have to create a new string "John" and assign it to s. It's the same when you add strings together. If do s += ' Smith', you are not going to get ' Smith' to be appended to the old value. What will happen is python will create a new string in a new memory location for you with the contents 'John Smith', and then assign that new value to s while the old value will be garbage collected later on.

Here, reading material about immutability https://realpython.com/python-mutable-vs...ble-types/
Reply
#6
Mutability does not apply to variables. variables are just names that reference objects. x can reference 2 or 3 or "dog" or a list. x references whatever was last assigned to x.

When python execute the code "x += 1", it gets the value referenced by x (lets say it was int 2) and adds 1. The sum (int 3) is a new object that assigned to the variable x. No objects have changed. x changed from referencing one object to referencing a different object. You can see this if you print the object ID of the object referenced by x before and after the operation.
x = 2
print(x, id(x))
x += 1
print(x, id(x))
Output:
2 140705246077768 3 140705246077800
johnywhy likes this post
Reply
#7
(Jan-15-2024, 01:35 AM)johnywhy Wrote: Unclear. x is mutable. I can say
x+=1

It's always good idea to read documentation:

3. Data model > 3.1.1. Objects, values and types:

Quote:The value of some objects can change. Objects whose value can change are said to be mutable; objects whose value is unchangeable once they are created are called immutable. (The value of an immutable container object that contains a reference to a mutable object can change when the latter’s value is changed; however the container is still considered immutable, because the collection of objects it contains cannot be changed. So, immutability is not strictly the same as having an unchangeable value, it is more subtle.) An object’s mutability is determined by its type; for instance, numbers, strings and tuples are immutable, while dictionaries and lists are mutable.

From glossary:

immutable:

Quote:An object with a fixed value. Immutable objects include numbers, strings and tuples. Such an object cannot be altered. A new object has to be created if a different value has to be stored. They play an important role in places where a constant hash value is needed, for example as a key in a dictionary.

mutable:

Quote:Mutable objects can change their value but keep their id(). See also immutable.
johnywhy likes this post
I'm not 'in'-sane. Indeed, I am so far 'out' of sane that you appear a tiny blip on the distant coast of sanity. Bucky Katt, Get Fuzzy

Da Bishop: There's a dead bishop on the landing. I don't know who keeps bringing them in here. ....but society is to blame.
Reply
#8
(Jan-15-2024, 02:07 AM)sgrey Wrote: python will create a new string in a new memory location
i think that's the key to immutability. But you still didn't explain why dictionaries are mutable.

(Jan-15-2024, 08:36 AM)perfringo Wrote: The value of an immutable container object that contains a reference to a mutable object can change when the latter’s value is changed; however the container is still considered immutable, because the collection of objects it contains cannot be changed
seems contradictory. "Mutable objects cannot be changed."

Are tuples the only immutable collection?

(Jan-15-2024, 08:36 AM)perfringo Wrote: Mutable objects can change their value but keep their id().
Does their address change?

Is this correct?
  • Mutable objects can change their value, while keeping the same memory address.
  • Immutable objects can only change their value by creating a new memory address.
  • Mutable collections are mutable, because an element at an index can be directed to a new memory address while keeping the same index.
Reply
#9
Immutable objects cannot change at all. The id of an object is a unique identifier. It may be the address of the object. The difference is moot since you cannot use the id to manipulate an object.
johnywhy likes this post
Reply
#10
(Jan-15-2024, 11:06 PM)johnywhy Wrote: i think that's the key to immutability. But you still didn't explain why dictionaries are mutable.
Because that's what their nature is. Dictionary is a collection that you can add or remove items to/from. As an alternative tuple is a collection that is immutable and you cannot remove or add items after it was created.
(Jan-15-2024, 11:06 PM)johnywhy Wrote: Is this correct?
  • Mutable objects can change their value, while keeping the same memory address.

  • Immutable objects can only change their value by creating a new memory address.

  • Mutable collections are mutable, because an element at an index can be directed to a new memory address while keeping the same index.
Generally this is ok to think this way. Except rather than value, you change object's state. Like, lists, for example, what is a value of a list? It's just a container that contains things, so you change the state of a container.

(Jan-15-2024, 11:06 PM)johnywhy Wrote: seems contradictory. "Mutable objects cannot be changed."

Are tuples the only immutable collection?

So, that text is a bit confusing, but it doesn't say that mutable objects cannot be changed. What it means is that if you have an object which is immutable, but inside that object you have another one that is mutable, you still consider the outer object immutable.
Here:
x = ([], [])
we have a tuple containing 2 lists. The tuple is immutable and you cannot change that. But, you can add items to both lists inside. If you do x[0].append(1), you will get ([1], []). So you are changing the state of objects inside the tuple, but what you cannot do is say x[0] = {} and change the list into a dictionary. So basically once you created an immutable object, all instances inside it will stay as they are, you cannot change their type or their number. But you can mutate their state, like adding elements to a list it holds, or assigning new values to a field inside an object inside a tuple.
johnywhy likes this post
Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  Find a specific keyword after another keyword and change the output sgtmcc 5 855 Oct-05-2023, 07:41 PM
Last Post: deanhystad
  Why doesn't calling a parent constructor work with arbitrary keyword arguments? PurposefulCoder 4 962 Jun-24-2023, 02:14 PM
Last Post: deanhystad
Question Keyword to build list from list of objects? pfdjhfuys 3 1,579 Aug-06-2022, 11:39 PM
Last Post: Pedroski55
  How to make global list inside function CHANKC 6 3,123 Nov-26-2020, 08:05 AM
Last Post: CHANKC
  Pattern Require Last Line Print() why? Harshil 4 2,446 Aug-08-2020, 04:54 PM
Last Post: Harshil
  Require Some Suggestions gouravlal 2 1,893 Jul-27-2020, 06:14 AM
Last Post: gouravlal
  search binary file and list all founded keyword offset Pyguys 4 2,787 Mar-17-2020, 06:46 AM
Last Post: Pyguys
  Where to put the global keyword when assigning variables outside a function? new_to_python 8 3,049 Feb-09-2020, 02:05 PM
Last Post: new_to_python
  Global variable does not seem to be global. Columbo 6 3,713 Jul-15-2019, 11:00 PM
Last Post: Columbo
  I converted string to 'list', but it doesn't look like a list! mrapple2020 3 3,260 Apr-07-2019, 02:34 PM
Last Post: mrapple2020

Forum Jump:

User Panel Messages

Announcements
Announcement #1 8/1/2020
Announcement #2 8/2/2020
Announcement #3 8/6/2020