0

So python dictionaries are mutable objects, hence when modified inside a function, the modification reflects also outside the function. However, when the function parameter is reassigned inside the function, the effect is only local.

For example consider the following code:

import json

def modify_dict1(a: dict) -> None: 
  new_dict = {1: "one"}
  a = new_dict


def modify_dict2(a: dict) -> None: 
  a[1] =  "1"
 

a_global = {1: "ONE"}
print(json.dumps(a_global, indent=2))
modify_dict1(a_global)
print(json.dumps(a_global, indent=2))
modify_dict2(a_global)
print(json.dumps(a_global, indent=2))

which prints:

{
  "1": "ONE"
}
{
  "1": "ONE"
}
{
  "1": "1"
}

I was expecting the output to be:

{
  "1": "ONE"
}
{
  "1": "one"
}
{
  "1": "1"
}

Why the reassignment to the local variable has no effect outside the function?

roschach
  • 8,390
  • 14
  • 74
  • 124
  • Well, you've answered it yourself: *reassignment to the local variable*. Assigning a new value to a *local variable* doesn't affect anything but the local variable. – deceze Jul 21 '23 at 08:31
  • But what's the rationale behind it? I mean if I can modify it using the local variable name, I was expecting the local variable being a reference, so that the reassignment should act the same way of a field modification. Why is this difference in behaviour desired? – roschach Jul 21 '23 at 08:56
  • Why is it a duplicate? The other question is asking how to pass a value by reference, here I am asking explanation about different behaviours. – roschach Jul 21 '23 at 09:01
  • 1
    The duplicate explains in a lot of detail how it works. This is a super common question in [tag:python] which we do not need to re-litigate. In a nutshell: `foo = bar` rebinds the name `foo` and makes it point at a new value. This does not affect the value that `foo` previously pointed to. `foo[bar] = baz` or similar things *mutate* the value that `foo` points to. – deceze Jul 21 '23 at 09:08

0 Answers0