Have list/deque grow a copy() method

It would be nice if containers had a more consistent interface. The standard idiom for copying a list has been L[:], but this isn't polymorphic and perhaps arcane. Also, deques can only be copied with the copy module's copy function (or calling the __copy__ wrapper directly); thus using copy.copy is the only polymorphic way to copy a mutable container. Additionally, having a consistent interface for mutable containers may dovetail with the ABC PEP. An alternate proposal would be to move copy.copy (and perhaps copy.deepcopy) into __builtins__. (Though this might be nice regardless.) As an aside, in addition to the copy method, list is the only mutable container not to have a clear method. Of course, del L[:] is the standard idiom for doing so, but this has the same problem of not being polymorphic. Perhaps having both del L[:] and L.clear() would violate the TOOWTDI principle, but L.reverse() can also be done with L = L[::-1] (maybe not the best example since they have different semantics.) Nevertheless, one is a lot easier to read. As for a use case, one might be a class that generalizes how it stores elements. For instance... class MutableUnorderedTree(AbstractTree): _storage_class = set class MutableOrderedTree(AbstractTree): _storage_class = list ...the latter has to be adapted to ensure consistent interface for methods like copy/clear. Well, that's my crackpot idea for today. - Ian D. Bolligner

"Ian D. Bollinger" <ian.bollinger@gmail.com> wrote:
It would be nice if containers had a more consistent interface. The standard idiom for copying a list has been L[:], but this isn't
The standard way of copying a list (or producing a list from an arbitrary sequence) is list(L).
polymorphic and perhaps arcane. Also, deques can only be copied with the copy module's copy function (or calling the __copy__ wrapper directly);
No, you can use deque(D).
I'm -0 on list.clear(), but can see why people would prefer it over del L[:] . Regarding your main proposal of inserting copy.copy into the builtins, I'm -1. Using the object constructors themselves as copying/creation procedures is generally seen to be a good practice, as it also typically allows users to pass *any* iterable and have it end up in a format that the recipient of the data wants. - Josiah

Georg Brandl <g.brandl@gmx.net> wrote:
No one needs to define a standard for it to be the standard. How would you propose, generally, to convert some arbitrary sequence into a list? Would you use a list comprehension: [i for i in seq] ? Would you use a generator expression passed to a list: list(i for i in seq) ? Or would you just use list(seq)? Me, I prefer simplicity and the case that works the way I usually need it to: list(seq). Conveniently, this works for list(dct), list(lst), list(deq), list(st), list(uni), list(tup), list(ite), ... To not use list(obj) when you can would seem to me to be an anti-pattern, regardless of the minor opimization that can be had in lst[:] copying. This technique is also going to be used in the 2to3 conversion utility to convert range() calls to list(range()) calls, and I am honestly baffled by anyone asking, "how do I copy a list, deque, dictionary,...". How could one *not* look at the base constructors? - Josiah

On Tuesday 15 May 2007, Ian D. Bollinger wrote:
copy.copy() and copy.deepcopy() have always been the only polymorphic ways to create copies. Is there any real motivation not to just use them? I've not found that I need a way to copy arbitrary objects very often, and haven't found the occaissional import of the copy module to be an obstruction. Are you needing to create lots of copies for some reason? -Fred -- Fred L. Drake, Jr. <fdrake at acm.org>

On 5/15/07, Fred L. Drake, Jr. <fdrake@acm.org> wrote:
For builtin container types (and many other container types as well): type(obj)(obj) is another polymorphic way to create copies. STeVe -- I'm not *in*-sane. Indeed, I am so far *out* of sane that you appear a tiny blip on the distant coast of sanity. --- Bucky Katt, Get Fuzzy

"Ian D. Bollinger" <ian.bollinger@gmail.com> wrote:
It would be nice if containers had a more consistent interface. The standard idiom for copying a list has been L[:], but this isn't
The standard way of copying a list (or producing a list from an arbitrary sequence) is list(L).
polymorphic and perhaps arcane. Also, deques can only be copied with the copy module's copy function (or calling the __copy__ wrapper directly);
No, you can use deque(D).
I'm -0 on list.clear(), but can see why people would prefer it over del L[:] . Regarding your main proposal of inserting copy.copy into the builtins, I'm -1. Using the object constructors themselves as copying/creation procedures is generally seen to be a good practice, as it also typically allows users to pass *any* iterable and have it end up in a format that the recipient of the data wants. - Josiah

Georg Brandl <g.brandl@gmx.net> wrote:
No one needs to define a standard for it to be the standard. How would you propose, generally, to convert some arbitrary sequence into a list? Would you use a list comprehension: [i for i in seq] ? Would you use a generator expression passed to a list: list(i for i in seq) ? Or would you just use list(seq)? Me, I prefer simplicity and the case that works the way I usually need it to: list(seq). Conveniently, this works for list(dct), list(lst), list(deq), list(st), list(uni), list(tup), list(ite), ... To not use list(obj) when you can would seem to me to be an anti-pattern, regardless of the minor opimization that can be had in lst[:] copying. This technique is also going to be used in the 2to3 conversion utility to convert range() calls to list(range()) calls, and I am honestly baffled by anyone asking, "how do I copy a list, deque, dictionary,...". How could one *not* look at the base constructors? - Josiah

On Tuesday 15 May 2007, Ian D. Bollinger wrote:
copy.copy() and copy.deepcopy() have always been the only polymorphic ways to create copies. Is there any real motivation not to just use them? I've not found that I need a way to copy arbitrary objects very often, and haven't found the occaissional import of the copy module to be an obstruction. Are you needing to create lots of copies for some reason? -Fred -- Fred L. Drake, Jr. <fdrake at acm.org>

On 5/15/07, Fred L. Drake, Jr. <fdrake@acm.org> wrote:
For builtin container types (and many other container types as well): type(obj)(obj) is another polymorphic way to create copies. STeVe -- I'm not *in*-sane. Indeed, I am so far *out* of sane that you appear a tiny blip on the distant coast of sanity. --- Bucky Katt, Get Fuzzy
participants (5)
-
Fred L. Drake, Jr.
-
Georg Brandl
-
Ian D. Bollinger
-
Josiah Carlson
-
Steven Bethard