Python Forum

Full Version: Global vs. Local Variables
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
I know I will probably be flamed for this question, but after 12 hours of researching and trying, this is my last resort. I know it is probably something simple I am overlooking, but now I have tunnel vision cant see it.

Question: How do I update an empty list at the global level, by passing a parameter to a function?

Example:

    >>> A = [] 
    >>> def Update(A = []):
            print("A =", A)
    >>> Update(44)
    A = 44
    >>> A
    []
Are you looking for something like this?
A = []

def update_dict(dname, value, clear=False):
    if clear:
        dname = []
    dname.append(value)
    print(f"Dict contents: {dname}")


update_dict(A, 44)
update_dict(A, 35)
update_dict(A, 55, clear=True)
Output:
Dict contents: [44] Dict contents: [44, 35] Dict contents: [55]
Not sure if this is what you want

spam = []

def update(my_list, value):
    my_list.append(value)

print(spam)
update(spam, 44)
print(spam)
Note that this will work only because spam is a list, i.e. mutable object. Basically your function would return

def double(value):
    return value * 2
eggs = 2
print(eggs)
eggs = double(eggs)
print(eggs)
also, there is another problem - never use mutable default arguments like in def Update(A=[]):

https://docs.python-guide.org/writing/go...-arguments
Please type code in files and execute the file. This is a lot less typing and my explanation will make a lot more sense if you are used to running Python this way. If your code was in a file I think the file would look like this:
A = []

def Update(A = []):
    print("A =", A)

Update(44)
print(A)
As far as Python is concerned the code below is the same as that above. Only the names have been changed to protect the innocent
A = []

def Update(this_is_a_function_arg = []):
    print("A =", this_is_a_function_arg)

Update(44)
print(A)
The 'A' in "def Update(A=[])" is a function parameter and has no relationship at all to the "A=[]" at the top of the file. The "A" in "A=[]" is a variable that is defined in the module scope. These two things are completely different.

When you call Update(44), the value 44 is assigned to the parameter "A". Inside the function the parameter "A" is available as a variable defined within the scope of the function. You can do stuff like get the value of the variable or set the value of the variable just like any other variable. Setting the parameter variable does not change the module variable. It doesn't matter if the two have the same name or not.

Your question is about lists and scope. A list is mutable meaning you can change the list by adding or removing items. Strings and numbers are immutable. You cannot change a string, you can only create a new string which is a modified version of an existing string. It may look like the string has changed, but the old string is still around, at least until garbage collection gobbles it up and frees up the memory.

Because lists are mutable you can change the list contents without having to make a new list. This code uses the mutability of lists to allow changing the content of a list in a function and have that change be seen outside the function.
def add_square_to_global(number):
    squares.append(number**2)

def add_square_to_list(squares_list, number):
    squares_list.append(number**2)

squares = []
add_square_to_global(2)
add_square_to_list(squares, 3)
add_square_to_global(4)
add_square_to_list(squares, 5)
print(squares)
Output:
[4, 9, 16, 25]
It should also be noted here that this does not work.
def list_of_squares(squares_list):
    squares_list = []
    for a in range(1, 11):
        squares_list.append(a**2)

squares_list = None
list_of_squares(squares_list)
print(squares_list)
Output:
None
This function creates a new list instead of modifying an existing list. The list created inside the function is assigned the function parameter and does not change the "squares_list" variable outside of the function. As before, the code may as well be written like this:
def list_of_squares(some_list):
    some_list = []
    for a in range(1, 11):
        some_list.append(a**2)

squares_list = None
list_of_squares(squares_list)
print(squares_list)
Python has a "global" keyword that tells Python to create a variable outside the function scope.
def init_squares_list():
    global squares_list
    squares_list = []
    for a in range(1, 11):
        squares_list.append(a**2)

init_squares_list()
print(squares_list)
Output:
[1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
This actually works, but as you write more Python code you'll see that this is really bad design. If you had several functions it would be difficult to see where "squares_list" was created. More importantly it is difficult to know when squares_list is created. The "squares_list" variable doesn't come into existence until the init_squares_list() function is called, and the code calling the function doesn't provide any indication that a list is created and assigned to a variable.

Instead of using "global" it is almost always better to have the function return the squares list.
Output:
def init_squares_list(): squares = [] for a in range(1, 11): squares.append(a**2) return squares squares_list = init_squares_list() print(squares_list)
This produces the same result as above, but the function call makes it obvious who is creating the squares_list.
Thank you ALL so much for taking the time to help me!

The examples and DETAILED explanations was and is more than I could have hoped for!

I am grateful for a place where a mini-pythoneer can come and be mentored!

RESPECT!!

DJXIV