Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Modifying dictionary inside a function

I have the following code:

def modify_dict(my_dict):
    my_dict = {'b': 2}
    print(my_dict)


def main():
    my_dict = {'a': 1}
    modify_dict(my_dict)
    print(my_dict)

if __name__ == '__main__':
    main()

and it's output is:

{'b': 2}
{'a': 1}

My question is why are the changes done to the dictionary inside the function aren't being reflected in the main() function?
Also, how can I update the dictionary inside the function so that the changes are reflected outside of the function?

like image 597
Anmol Singh Jaggi Avatar asked Apr 13 '16 13:04

Anmol Singh Jaggi


2 Answers

The my_dict parameter of modify_dict is a local variable to your function. It contains a reference to your dictionary, but it itself is simply a local variable. If you reach in and modify the dictionary it points to, that would work. For example:

def modify_dict(my_dict):
    my_dict['b'] = 2
    print(my_dict)

Will add to your dictionary. In effect, you are simply assigning a new dictionary to a local variable called my_dict in your function.

As @vmonteco suggests, the best way to achieve this is to simply return the new dictionary from your function and assign the return value.

like image 144
srowland Avatar answered Oct 04 '22 22:10

srowland


This is an interesting question, I will try to give a shot. My major programming language is Java, but I think CPython&JVM are the same in this case.

In program runtime, it got stack and heap, the stack is used on method call context storage and the heap is for global objects storage.

ok, then, use you code as example

step 1.

my_dict = {'a': 1}

it will create a dict(1) {'a': 1} in heap, and then my_dict is reference to the memory address of the dict(1), it means my_dict now is point to an memory address, but not the {'a': 1} itself.

step 2.

my_dict = modify_dict()

ok, then we call modify_dict function inside main function, the program will put context of main function into a stack(stack1), and the go into function modify_dict with my_dict as argument, now, the program will create a new stack for function modify_dict, and make a copy of arguments, this means my_dict argument now is a reference copy (point to the dict(1) in heap, got the same value as my_dict variable in main, but it's a copy). (indeed, the question has been answer here)

step 3:

my_dict = {'b': 2}

my_dict (a reference point to dict(1) in the heap) now is assign to a new dict(2) in heap, remember my_dict now is not the same with my_dict in main, they are point to two different dict in the heap.

step 4:

program return back to main function, program will pull things from stack, my_dict now is point to dict(1), and dict(1) is not modify in function modify_dict

Sorry for my poor english :)

like image 33
NewBee Avatar answered Oct 04 '22 22:10

NewBee