0

I have a global variable, things (a list), used within two functions. In one function, save_thing, I want to save the original variable as a value to a key in a dictionary that when printed, shows: {'First thing': ['a', 'b']}. I can successfully do this.

In another function, change_thing, I want to use a copy of things (a local variable) only within change_thing. Then I want to remove the first list item, 'a', from the local variable. But I can't figure out how to make a copy of the global variable used locally. Instead, the global variable is changed, and the dictionary used in the first function, save_thing, is changed. And I don't want that.

I thought that passing the global variable as an argument/parameter in the function would make it be used locally, but that is wrong. I understand that in my code, the global variable (things) is set as the value in the dictionary and when the change_thing function alters the global variable, the dictionary is also altered.

Ultimately, I want to understand how to pass global variables into functions and use them locally without changing the global. I haven't been able to find examples of this elsewhere.

things = ['a', 'b']
dictionary = {}

def save_thing(parameter):
    dictionary['First thing'] = parameter
    print('Dictionary BEFORE change_thing is run', dictionary)

def change_thing(parameter):
    parameter.remove('a')

save_thing(things)
change_thing(things)
print('Dictionary AFTER change_thing is run', dictionary)

When run, the above code prints:

Dictionary BEFORE change_thing is run {'First thing': ['a', 'b']} Dictionary AFTER change_thing is run {'First thing': ['b']}

I want the dictionary to always be {'First thing': ['a', 'b']} and not impacted by the change_thing function.

Any feedback is appreciated. Thanks.

JohnG
  • 3
  • 3
  • Does this answer your question? [Using global variables in a function](https://stackoverflow.com/questions/423379/using-global-variables-in-a-function) – Blue Robin Mar 27 '23 at 18:26
  • I believe you are creating a reference and not a copy. You can use `list.copy` to copy a list. – Blue Robin Mar 27 '23 at 18:28
  • Blue Robin... Appreciate the link to 'Using global variables in a function.' I'm struggling to find a relatable solution since I'm not seeing an example in that thread using a list. But your list.copy suggestion may work. I'll give it a try. Thanks. – JohnG Mar 27 '23 at 18:46
  • .copy() on a list passed to a function has helped me do what I want. Thank you! – JohnG Mar 27 '23 at 19:26
  • Welcome! I had the same issue a long time ago. – Blue Robin Mar 27 '23 at 19:26

1 Answers1

0

Thanks to Blue Robin in the comments for helping sort this out. A local instance of the global variable for things can be made using .copy(). This then allows me to write the data to the dictionary where I'm tracking data to be saved. In a later function, I can then modify the global variable without writing over the data written in the dictionary.

The new code is this (with some rewrites of the function arguments to make more sense).

things = ['a', 'b']
dictionary = {}

def save_thing(list_arg):
    saved_list = list_arg.copy()
    dictionary['First thing'] = saved_list
    print('Dictionary BEFORE change_thing is run', dictionary)

def change_thing(list_arg):
    list_arg.remove('a')

save_thing(things)
change_thing(things)
print('Dictionary AFTER change_thing is run', dictionary)

Program now prints: Dictionary BEFORE change_thing is run {'First thing': ['a', 'b']} Dictionary AFTER change_thing is run {'First thing': ['a', 'b']}

JohnG
  • 3
  • 3
  • 1
    Good answer except it does the opposite of what the question asks: _In another function, change_thing, I want to use a copy of things (a local variable) only within change_thing._ If that's the case, you'd want to do the copy in `change_thing`. – tdelaney Mar 27 '23 at 20:33
  • And just to keep things complicated, there is also a module `copy` with function `deepcopy` that will also copy the objects internal to the list. Suppose `things = ['a', ['foo', 'bar']]`. `list.copy` will not make a new copy of the foobar list, but deepcopy would. – tdelaney Mar 27 '23 at 20:34