tags:

views:

112

answers:

6
+2  Q: 

Python list help

simple Python question:

Example list: A = [1,2,3,4,5]

I need to generate another list B which is a shallow copy of list A such that B is a new list containing the same elements in the same order (so that I can substitute one of B's elements w/o affecting A). How can I do this?


clarification: I want to do something like

def some_func(A)
   B = {what do I do here to get a copy of A's elements?}
   B[0] = some_other_func(B[0])
   yet_another_func(B)

based on all your answers + the Python docs, a better way to do what I want is the following:

def some_func(A)
   B = [some_other_func(A[0])] + A[1:]
   yet_another_func(B)

thanks for pointing me in the right direction!

+8  A: 

That would be a deep copy, not a shallow one.

Lists copy shallow by default. That's why there's a deepcopy command in the copy module.

B = copy.deepcopy(A)

Optionally, B = A[:] will do. But keep deepcopy in mind for future. More complex data types can benefit from it.


Added Info about copy:

A shallow copy:

b = [1,2]
a = b
b[0] = 11
print a  // [1,11]

A deep copy:

b = [1,2]
a = b[:]
b[0] = 11
print a  // [1,2]

But, furthermore:

>>> a = [[1,2]]
>>> b = a[:]
>>> b
[[1, 2]]
>>> a
[[1, 2]]
>>> a[0][0] = 11
>>> a
[[11, 2]]
>>> b
[[11, 2]]
>>>

So, the elements themselves are shallow copies in this case.

JoshD
+1 for splitting important hairs :-)
Jason S
@Jason S, thanks. I learned something with this question. So +1 to you, too!
JoshD
+3  A: 

B=A[:] suffices:

In [22]: A=[1,2]

In [23]: B=A[:]

In [24]: B[0]=100

In [25]: A
Out[25]: [1, 2]

In [26]: B
Out[26]: [100, 2]

A[:] uses slice notation to get the slice with all the elements of A. Since slices of Python lists always return new lists, you get a copy of A.

Note that the elements inside B are identical to the elements inside A. If the elements are mutable, mutating them through B will affect A.

unutbu
I think we all need to clarify when we mean a shallow copy of the list and a shallow copy of the elements in the list. When I hear shallow copy of a list, I think of `a=b`. What you've done, I would call a deep copy, even though the elements themselves are shallow copy, the _list_ is a deep copy.
JoshD
@JoshD: I think you are right, I was misusing the term "shallow copy" as defined here: http://en.wikipedia.org/wiki/Shallow_copy#Shallow_copy
unutbu
It's an awkward situation because both are happening. A is a deep copy of B, but A[0] is a shallow copy of B[0]. Your current answer is excellent and clears this up perfectly. +1
JoshD
+3  A: 

Like this:

B = A[:]
Quartz
+2  A: 
import copy
A=[1,2,3,4,5]
B=copy.copy(A)
B[0]=9999
print B[0]
print A[0]

import copy and use copy.copy() for copying. see this for reference.

Sujoy
+2  A: 

You can perform that copy in the following way:

B = A[:]
Brandon E Taylor
+5  A: 

Here are 3 ways to make a copy of list A:

Use slice notation:

copy_of_A = A[:]

Use the list constructor:

copy_of_A = list(A)

Use the copy module:

from copy import copy
copy_of_A = copy(A)

As you requested these copies are all shallow copies. To learn about the difference between shallow copy and deep copy read the documentation of the copy module.

Steven Rumbalski
+1 for citing the copy docs for terminology.
Jason S
@Jason S, I guess I should have been more explicit with my link :) Also +1. nice answer.
JoshD