-1

I need some clarification on this concept here, I am trying out .deepcopy() in python and I have read that:

A deep copy constructs a new compound object and then, recursively, inserts copies into it of the objects found in the original.

However, In my code below, I can see that IDs for x[0] = y[0] and x[1] = y[1], but ID for x[2] != y[2], which makes sense because it inserts copies of the object. But why is ID of x[0] equals y[0] and x[1] equals y[1]?

This is the code that I tried:

x=[1,2,[3,4]]
y=cp.deepcopy(x)
print(id(x),id(y))

for i in range(len(x)):
    print(id(x[i]),id(y[i]))

Output:

923236765248 923256513088
140729072564000 140729072564000
140729072564032 140729072564032
923256458496 923256516928
quamrana
  • 37,849
  • 12
  • 53
  • 71
jaideep
  • 13
  • 1
  • 5
  • 3
    You won't be able to verify this behaviour just using `int`s. They are optimised to have the same `id`. Try a simple wrapper around them and you will see that you get new objects. – quamrana Apr 23 '21 at 20:44
  • I think this has to do with reference types vs value types somewhere in the interpreter – asdf101 Apr 23 '21 at 20:44
  • 2
    It only copies mutable objects. – Barmar Apr 23 '21 at 20:45
  • 1
    @quamrana Just to be precise, that optimization is only done for small integers. – Barmar Apr 23 '21 at 20:46
  • Pretty sure @quamrana and barmar have it right. yes this is a deep copy, if you change the value at y[2][0] it will not change the value at x[2][0], but they will have the same id before the change is made. – LPR Apr 23 '21 at 20:46
  • related https://stackoverflow.com/questions/42714569/cant-understand-python-shallow-copy-when-working-with-int-and-str?rq=1 – asdf101 Apr 23 '21 at 20:47
  • Every integer has same id upto a certain limit. Try `id(1)` a bunch of times and you will get the same value. – Albin Paul Apr 23 '21 at 20:54

1 Answers1

1

In this exanple, I am using obj as a wrapper around another value:

import copy as cp

class obj:
    def __init__(self, i):
        self.i = i
    def __repr__(self):
        return f'obj({self.i})'


x=[obj(1),obj(2),[obj(3),obj(4)]]
y=cp.deepcopy(x)
print(id(x),id(y))

for i in range(len(x)):
    print(id(x[i]),id(y[i]))

Output shows all different numbers.

quamrana
  • 37,849
  • 12
  • 53
  • 71