Deeper copy than deepcopy

S

Scott Pakin

copy.deepcopy apparently preserves multiple references to the same object:

$ python
Python 2.5.2 (r252:60911, Jan 4 2009, 17:40:26)
[GCC 4.3.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import copy
>>> d = [1,2,3]
>>> r = copy.deepcopy([d]*3)
>>> r [[1, 2, 3], [1, 2, 3], [1, 2, 3]]
>>> r[1][2] = 999
>>> d [1, 2, 3]
>>> r [[1, 2, 999], [1, 2, 999], [1, 2, 999]]
>>>

I wanted to wind up with r being [[1, 2, 3], [1, 2, 999], [1, 2, 3]].
What's the right way to construct r as a list of *independent* d lists?

Thanks,
-- Scott
 
C

Cameron Simpson

| copy.deepcopy apparently preserves multiple references to the same object:
|
| $ python
| Python 2.5.2 (r252:60911, Jan 4 2009, 17:40:26)
| [GCC 4.3.2] on linux2
| Type "help", "copyright", "credits" or "license" for more information.
| >>> import copy
| >>> d = [1,2,3]
| >>> r = copy.deepcopy([d]*3)
| >>> r
| [[1, 2, 3], [1, 2, 3], [1, 2, 3]]
| >>> r[1][2] = 999
| >>> d
| [1, 2, 3]
| >>> r
| [[1, 2, 999], [1, 2, 999], [1, 2, 999]]
| >>>
|
| I wanted to wind up with r being [[1, 2, 3], [1, 2, 999], [1, 2, 3]].
| What's the right way to construct r as a list of *independent* d lists?

Well, you would need to write your own. But consider this:

x = [1, 2]
x.append(x)

Your deepercopy() function will explode.

Probably the best method is to pre-munge the list you pass to deepcopy:

d = [1,2,3]
d3 = [d]*3
# pre-copy the multiple references
d3deeper = [ list(d3i) for d3i in d3 ]
r = copy.deepcopy(d3deeper)

You can see this requires special knowledge of the structure you're
copying though.
--
Cameron Simpson <[email protected]> DoD#743
http://www.cskk.ezoshosting.com/cs/

The mere existence of a problem is no proof of the existence of a solution.
- Yiddish Proverb
 
G

Gary Herron

Scott said:
copy.deepcopy apparently preserves multiple references to the same object:

$ python
Python 2.5.2 (r252:60911, Jan 4 2009, 17:40:26)
[GCC 4.3.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.
import copy
d = [1,2,3]
r = copy.deepcopy([d]*3)
r [[1, 2, 3], [1, 2, 3], [1, 2, 3]]
r[1][2] = 999
d [1, 2, 3]
r [[1, 2, 999], [1, 2, 999], [1, 2, 999]]

I wanted to wind up with r being [[1, 2, 3], [1, 2, 999], [1, 2, 3]].
What's the right way to construct r as a list of *independent* d lists?

Thanks,
-- Scott

Try this:
>>>
>>> d = [1,2,3]
>>> r = [[x for x in d] for i in range(3)]
>>> r[1][2] = 999
>>> r
[[1, 2, 3], [1, 2, 999], [1, 2, 3]]

Gary Herron
 
S

Scott Pakin

Thanks everyone! The list-comprehension approach should work in my case
as I know a priori that my data structure is finite. Still, it'd be
awfully convenient for Python's copy module to offer a copy.deepercopy
function -- even if it comes with the caveat that it will explode if
given a data structure with backlinks.

Regards,
-- Scott
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,982
Messages
2,570,190
Members
46,736
Latest member
zacharyharris

Latest Threads

Top