Skip to content

Comment on Python: copying a list the right way

Comments

Unless you actually want to turn some other type of iterator into a list, why wouldn't you use python's generic copy?

  from copy import copy
  b = copy(a)
This has the advantage of being advertised as a shallow copy, so the intent of the operation and its effects are clear and well-documented.

I've been working with Python for a year now, and I don't claim to have swum its depths.

Because copy won't necessarily work the same way on things that are not lists, which removes some of the flexibility afforded by python's duck typing. Unless you have good reason to require a list specifically, why should you?

But don't the alternatives also depend on list slicing? Heck, the title is `coping a list`. If you have a different datatype, it is the business of that type to specify how to copy using __copy__, isn't it?

Imagine a case like this:

  def example(input_data):
    l = list(input_data)
    # code that uses list-specific stuff and returns a result
The function 'example' doesn't want to touch the original input data, so it needs to make a copy of it. It also contains code that assumes operation on a list, so the copied value needs to support list-like operators. If you assume input_data is a list, you can use [:] or copy() to copy just fine, but if input_data is NOT a list then you cannot feed example a generator or some other list-like object or iterable and know for sure that it is going to work. By explicitly converting to list, you can take anything that implements __iter__, and then safely assume that the rest of your code will be working with lists. This adds a pretty bit of extra flexibility to the function and can make it much easier and/or cleaner to use.

Obviously as with anything the choice of list copy method is situation-dependent. Using [:] makes sense if you can guarantee the input is a list and you need maximal speed. Using copy() makes sense if you just want a copy of the input object and don't specifically care that the copy is itself a list. Using list() makes sense if you want to be able to take in all kinds of input values and be assured that the copy is a list. Use what is best for the situation at hand.

You can't copy a generator that way.

Using list(gen) will fully consume the generator, which may be undesirable, but at least it will generate a list with the correct values.

AboutSource Built by g1lg1l

Hackerly is an independent reader for Hacker News, built on the public HN API. Not affiliated with Y Combinator.