Wednesday, July 24, 2013

Python object copy

We ran into a problem, which made me puzzled at the beginning. After minutes of debug, I realized I was in the "object reference" trap which I thought would never meet it :(
Here's the simplified code

"set a" changed since 2nd loop while we were expecting it as a consistent value.

From the output we got some information
- memory address of variable delta was re-allocated in every loop -> line#14,18,22
- item we changed 3 times in line #9, but they affected on same object because the id remains same line#15,19,23. And that's why the problem occur.

Analysis result: from the memory address we printed, we found that the object we changed(item, from delta), is no doubt a member in "set a".
The item is a

object reference

of an element of "set a"

We can created a copy of "delta" instead of reference to "set a", but there're 2 kinds of copy in Python. Shallow copy and deep copy.

Shallow copy

Deep copy

Pseudo code

Python code
Pseudo code

a = [1,2]
Node** pa=new Node*[3];
pa[0] = new Node(1);
pa[1] = new Node(2);
pa[2] = new Node*[2](1,2);

reference operation
b = a
b is a #True
id(b) == id(a) #True
id(b[0]) == id(a[0]) #True

Node**& pb = pa; //C++ reference
printf("%p", pa)
printf("%p", pb)
shallow copy
b is a #False
id(b) == id(a) #False
id(b[0]) == id(a[0]) #True
Node** pb=new Node*[3];
pb[0] = pa[0];
pb[1] = pa[1];
pb[2] = pa[2];
deep copy
import copy
b = copy.deepcopy(a)
id(b) == id(a) #False
id(b[0]) == id(a[0]) #False
Node** pb=new Node*[3];
pb[0] = new Node(pa[0]);
pb[1] = new Node(pa[1]);
pb[2] = new Node(pa[2]);