Why aren't copy and deepcopy in __builtins__?
Steven D'Aprano
steve+comp.lang.python at pearwood.info
Mon Mar 28 17:23:28 EDT 2011
On Mon, 28 Mar 2011 10:30:03 -0700, John Ladasky wrote:
> On Mar 28, 2:25 am, Andrea Crotti <andrea.crott... at gmail.com> wrote:
>> John Ladasky <lada... at my-deja.com> writes: I almost never use them
>> either, maybe also in many cases you could avoid using them...
>> When for example you use them?
>
> To take one example: neural network programming. I construct a network
> object (which is quite complex), test it, and keep it. Next, I copy the
> network object, apply a slight variation to it, and test that. If the
> variant performs less well than the original, I discard the variant, and
> try another slightly-varied copy of the original. If the variant is
> superior, I discard the original. And so on.
Without knowing the details of your neural network code, it isn't clear
that *copying* is the right way to do this. Presumably you initialize
your network object with some set of input parameters, as in:
obj = neural_network(a, b, c, d, e, f)
Those input params are probably far less complex than the internal
details of the object, particularly after it is trained. It is probably
faster and simpler to create a new variant directly from the modified
parameters:
obj = neural_network(a, b, c, d+1, e, f) # (say)
but of course your mileage may vary.
> Another use: When I'm profiling code for speed, I generate a sequence of
> function calls in a specific order. I would like to retain that ordered
> sequence for when I print out the results of my speed test, but also
> generate shuffled variations of that sequence. But random.shuffle()
> alters the sequence in place, it does not return a copy. If shuffle()
> did return a copy, I would not need to invoke copy myself, but that's
> how the library function is written.
Just make sure you're using a standard list (as opposed to some arbitrary
sequence), and then use string-slicing to make a copy:
func_calls = [a, b, c, d, e, f]
another = func_calls[:]
shuffle(another)
If the string-slicing notation is too mysteriously Perl-like for you, you
can write that line as:
another = list(func_calls)
There's usually no need for a deep copy, particularly if you're writing
code in a semi-functional style with a minimum of in-place modifications
-- a shallow copy will do.
I don't believe I have ever needed to use either copy.deepcopy or
copy.copy in production code. Normally techniques like list slicing, list
comprehensions, {}.copy() and similar are more than enough. It's nice to
have the copy module there as a fall-back if I should ever need it, but I
haven't needed it yet.
--
Steven
More information about the Python-list
mailing list