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"
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).
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.
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
Josiah Carlson schrieb:
"Ian D. Bollinger"
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).
The first part is news to me. Who defined that standard? Georg
Georg Brandl
Josiah Carlson schrieb:
"Ian D. Bollinger"
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).
The first part is news to me. Who defined that standard?
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
Josiah Carlson schrieb:
Georg Brandl
wrote: Josiah Carlson schrieb:
"Ian D. Bollinger"
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).
The first part is news to me. Who defined that standard?
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?
No, I meant the "copying a list" part. Getting a list from an iterable is easiest with list(), of course. Georg
Georg Brandl
Josiah Carlson schrieb:
Georg Brandl
wrote: Josiah Carlson schrieb:
"Ian D. Bollinger"
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).
The first part is news to me. Who defined that standard?
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?
No, I meant the "copying a list" part. Getting a list from an iterable is easiest with list(), of course.
I choose as standard what works in the most cases. Since list() works everywhere, using it on lists makes the most sense to me. - Josiah
"Ian D. Bollinger"
Josiah Carlson wrote:
I choose as standard what works in the most cases. Since list() works everywhere, using it on lists makes the most sense to me.
Good point. Would it be worth specifying this in the official style guide?
I think that would be more hand-holding than we really want to be doing. - Josiah
On Tuesday 15 May 2007, Ian D. Bollinger 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 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.
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.
On Tuesday 15 May 2007, Ian D. Bollinger 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 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.
copy.copy() and copy.deepcopy() have always been the only polymorphic ways to create copies.
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
On Tuesday 15 May 2007, Steven Bethard wrote:
For builtin container types (and many other container types as well): type(obj)(obj) is another polymorphic way to create copies.
If you're willing to rely on the constructor signature, sure. For many applications, the convention that the constructor can be used as a copier doesn't hold. -Fred -- Fred L. Drake, Jr. <fdrake at acm.org>
"Fred L. Drake, Jr."
On Tuesday 15 May 2007, Steven Bethard wrote:
For builtin container types (and many other container types as well): type(obj)(obj) is another polymorphic way to create copies.
If you're willing to rely on the constructor signature, sure. For many applications, the convention that the constructor can be used as a copier doesn't hold.
But for builtin types (which is the only objects we can reliably change), using the base constructor to copy an object *does* work for all container types (except for defaultdict). - Josiah
participants (5)
-
Fred L. Drake, Jr.
-
Georg Brandl
-
Ian D. Bollinger
-
Josiah Carlson
-
Steven Bethard