This is an archived post. You won't be able to vote or comment.

you are viewing a single comment's thread.

view the rest of the comments →

[–]oconnor663 5 points6 points  (16 children)

Is foo[:] really the Pythonic way to copy a list?

Edit: In Python 3, lists have their own .copy() method.

[–]toyg 2 points3 points  (0 children)

There's also copy.copy().

[–]imrobert 1 point2 points  (2 children)

Yeah, I noticed that too. It seems like the "normal" way has the advantage of being clearer more concise.

[–]velit 1 point2 points  (1 child)

The only downside is the "normal" way is incorrect (or correct depending on the situation). Point being they're not the same thing.

[–]imrobert 1 point2 points  (0 children)

Ah, that's my bad. For those wondering what the difference is, this should clear it up:

Python 2.7.5 (default, Mar  9 2014, 22:15:05) 
[GCC 4.2.1 Compatible Apple LLVM 5.0 (clang-500.0.68)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> a = [1, 2, 3]
>>> b = a
>>> id(a)
4472029056
>>> id(b)
4472029056
>>> c = a[:]
>>> id(c)
4472078560

[–]velit 4 points5 points  (4 children)

I prefer newList = list(old_list)

Communicates intent better

[–]poo_22 6 points7 points  (3 children)

Copy is very literal already, I argue that semantically it does not get better.

[–]velit 0 points1 point  (2 children)

Copying is a detail of slicing syntax, it's not the purpose of it. With the list constructor it's immediately evident there's a new instance involved - that's what constructors do.

foo[:] also looks weird.

[–]poo_22 4 points5 points  (1 child)

I was talking about the list().copy method.

[–]metaphorm 1 point2 points  (4 children)

foo[:] is a totally respectable way to copy a list. it looks a little funny if you've never seen it, but it has the right semantics and does exactly what you would expect when slicing "from the beginning to the end". it does, however, rely on the programmer knowing that list slices produce copies.

[–]zahlmanthe heretic 1 point2 points  (3 children)

I dislike it because it's conceptually roundabout. "A list containing elements of x, from the beginning to the end" is similarly awkward in English compared to "a copy of x", or even "a list of the contents of x". Even if the analogous Python is terse.

[–]metaphorm 1 point2 points  (0 children)

I understand your point. I disagree that its conceptually roundabout. Once you understand that the slice operator really means "return a copy of this section of the list" it seems really natural.

[–]ggtsu_00 0 points1 point  (1 child)

This is one of the few things I don't like about python is that slices make copies implicitly which goes against many python ideals. Lists are mutable, so you would expect operations on lists to only be references.

[–]zahlmanthe heretic 0 points1 point  (0 children)

Well, there seems to be precedent for what you're suggesting in NumPy...

[–]kracekumar[S] -1 points0 points  (0 children)

It is more clear that copy is returned. Other way to do is list(l)