-2

I need to work with dict from dict as a copy, but when I change this copy, the original dict changes too. The question is: "Is there any specific documentation, that describes this Python behavior?"

b = {"first_first": 10} # internal dict

a = {"first": b, "second": 5}  # full dict

print(a)  # {'first': {'first_first': 10}, 'second': 5}

x = a["first"] # new object creation (want to get a copy of the internal dict)
x["first_first"] = 8  # created object modification

print(a)  # {'first': {'first_first': 8}, 'second': 5} # Why was initial dict changed? Seems that 
# line : x = a["first"] passes a reference
Alexey Kolosov
  • 140
  • 2
  • 15
  • 5
    *"behaves like object reference"* — That's because it is. – deceze Mar 29 '21 at 10:06
  • What happened when you tried putting, for example, `python pass by reference` into a search engine? Stack Overflow is not intended to replace existing tutorials or documentation, and recommendations for specific documentation sources are off-topic because they are too subjective. That said, the language has *official* documentation on docs.python.org; the table of contents has a big shiny "language reference" category, and from there you can easily get to the [relevant section](https://docs.python.org/3/reference/executionmodel.html#naming-and-binding). – Karl Knechtel Mar 29 '21 at 10:09
  • **Nowhere** did you make a copy. Note, dict objects are objects, everything in Python is an object. Why do you think `x = a["first"]` would create a copy? Did you think `a["first"]` would create a copy? Python is *neither* call by value nor call by reference, but that isn't really relevant here. – juanpa.arrivillaga Mar 29 '21 at 10:28
  • Note, assignment never makes a copy, i.e. just because you do `x = ` does not imply you are creating a new object at all, you are merely assigning some object to the name `x`. Now, you could define your own container type which *did* create a copy when you index/keyed into it, e.g. `my_custom_map["first"]` *could potentially* create a copy, but that is never really the case for built-in types, although, there may be a couple examples in the standard library (e.g. `shelve` objects). Probably good to read: https://nedbatchelder.com/text/names.html – juanpa.arrivillaga Mar 29 '21 at 10:46

1 Answers1

0

By doing a["first"] you will get a reference to the internal object (here a dictionary)

If you want to modify the dictionary without impacting the inital dict, you must explicity create a new one. There are different ways to do this. You can simply do:

x = dict(a["first"])

or

x = a["first"].copy()
Cyrille Pontvieux
  • 2,356
  • 1
  • 21
  • 29