Implementing deepcopy
Alex Martelli
aleax at mail.comcast.net
Wed Dec 7 22:39:14 EST 2005
Mr.Rech <andrea.riciputi at gmail.com> wrote:
...
> Suppose one of the attributes of my class is a dictionary whose values
> are callable functions, such as:
>
> >>>def foo():
> ..... pass
> >>>def bar():
> ..... pass
>
> >>>adict = dict(a = foo, b = bar)
>
> Now if I try:
>
> >>> anotherdict = copy.deepcopy(adict) # It doesn't work
Right, because functions are not copyable (although you could, if you
wished, write a way to copy them and copy_reg it).
> however:
>
> >>> anotherdict = copy.copy(adict) # works as expected
Right, as it's a shallow copy.
> My question is: anotherdict is really a copy of adict? If so, what is
> the difference between its definition and the following:
>
> >>> yanotherdict = dict(adict)
No difference whatsoever, and in fact
>>> guesswhat = adict.copy()
is yet another way to do just the same thing -- a shallow copy.
The use of copy.copy(foo) is recommended when you aren't sure what type
you're dealing with in 'foo', but want the same identical type as a
result; the use of dict(foo) is recommended when you aren't sure what
type you're dealing with in 'foo', but want a dict as a result.
If you're certain you're dealing with a dict, then, if this code is
critical for your app's performance, pick the fastest way. Use timeit
to find the fastest way, e.g., on my iBook:
Helen:~ alex$ python -mtimeit -s'd=dict.fromkeys(range(99))' -s'import
copy' 'copy.copy(d)'
100000 loops, best of 3: 17.3 usec per loop
Helen:~ alex$ python -mtimeit -s'd=dict.fromkeys(range(99))' -s'import
copy' 'd.copy()'
100000 loops, best of 3: 11.4 usec per loop
Helen:~ alex$ python -mtimeit -s'd=dict.fromkeys(range(99))' -s'import
copy' 'dict(d)'
100000 loops, best of 3: 12.8 usec per loop
Helen:~ alex$
I would avoid copy.copy (measurably slower) and end up using (as I
usually do...) dict(d), but I wouldn't bitch against anybody choosing to
use d.copy() instead for a 10%-or-so gain in speed.
Personally, I find that list(L), dict(D), set(S) and so on are the best
way to perform shallow copies for known-type objects, and strongly
dislike type-specific divergences such as L[:] and D.copy() and
S.copy(), but there's no community consensus on this point.
Alex
More information about the Python-list
mailing list