2008-10-08 10 views

Respuesta

86

Si desea una copia superficial (elementos no se copian) usan:

lst2=lst1[:] 

Si desea hacer una copia en profundidad a continuación, utilizar el módulo de copia:

import copy 
lst2=copy.deepcopy(lst1) 
+1

¿Qué quiere decir con elementos no copiados? – sheats

+4

Si los elementos son objetos mutables, se pasan por referencia, debe utilizar Deepcopy para copiarlos realmente. –

+2

Copiará solo las referencias retenidas por la lista. Si un elemento en la lista contiene una referencia a otro objeto, eso no se copiará. 9 veces de cada 10 solo necesita la copia superficial. –

18

Uso a menudo:

lst2 = lst1 * 1 

Si lst1 contiene otros contenedores (como otras listas) debe usar deepcopy de la copia de copia como se muestra en Marcos.


ACTUALIZACIÓN: Explicando deepcopy

>>> a = range(5) 
>>> b = a*1 
>>> a,b 
([0, 1, 2, 3, 4], [0, 1, 2, 3, 4]) 
>>> a[2] = 55 
>>> a,b 
([0, 1, 55, 3, 4], [0, 1, 2, 3, 4]) 

Como se puede ver sólo un cambió ... voy a tratar ahora con una lista de listas

>>> 
>>> a = [range(i,i+3) for i in range(3)] 
>>> a 
[[0, 1, 2], [1, 2, 3], [2, 3, 4]] 
>>> b = a*1 
>>> a,b 
([[0, 1, 2], [1, 2, 3], [2, 3, 4]], [[0, 1, 2], [1, 2, 3], [2, 3, 4]]) 
No

manera legible, déjame imprimirlo con a para:

>>> for i in (a,b): print i 
[[0, 1, 2], [1, 2, 3], [2, 3, 4]] 
[[0, 1, 2], [1, 2, 3], [2, 3, 4]] 
>>> a[1].append('appended') 
>>> for i in (a,b): print i 

[[0, 1, 2], [1, 2, 3, 'appended'], [2, 3, 4]] 
[[0, 1, 2], [1, 2, 3, 'appended'], [2, 3, 4]] 

¿Lo ves? Se adjuntó a la b [1] también, por lo que b [1] y a [1] son ​​el mismo objeto. Ahora intenta con deepcopy

>>> from copy import deepcopy 
>>> b = deepcopy(a) 
>>> a[0].append('again...') 
>>> for i in (a,b): print i 

[[0, 1, 2, 'again...'], [1, 2, 3, 'appended'], [2, 3, 4]] 
[[0, 1, 2], [1, 2, 3, 'appended'], [2, 3, 4]] 
+2

'copy()' no funcionará en el último caso, necesita 'deepcopy()' siempre que tenga una referencia dentro del objeto. –

+1

Pensé que tu truco de usar 'lst1 * 1' era realmente bueno ... pero, por desgracia, el perfil aproximado sugiere que es al menos dos veces más lento que' lst1 [:] ', que es ligeramente más rápido que' copy (last1) '. – Andrew

2

También puede hacer esto:

import copy 
list2 = copy.copy(list1) 

Esto debería hacer lo mismo que la copia superficial de Mark Roddy.

12

También puede hacer:

a = [1, 2, 3] 
b = list(a) 
+2

¿El resultado es una copia superficial o profunda? – minty

+8

No, usar list() es definitivamente una copia superficial. Pruébalo. –

+2

¿Hay una diferencia de velocidad? Podría decirse que cuando haces '[:]', la biblioteca es lo suficientemente inteligente como para saber que se está haciendo una copia y, por lo tanto, podría invocar un código C nativo para hacerlo. Con 'list (iterable)' ¿sabe/cuida que el iterable ya está materializado y, por lo tanto, puede copiarse de manera eficiente? –

6

me gusta hacer:

lst2 = list(lst1) 

La ventaja sobre lst1 [:] es que el mismo lenguaje que funciona para dicts:

dct2 = dict(dct1) 
+0

En realidad, hubo una discusión bastante larga sobre la copia del diccionario contra la lista en la lista de correo de Python 3K: http://mail.python.org/pipermail/python-3000/2008-February/thread.html#12052 –

+0

The un poco de información aquí es que para los diccionarios, puede hacer d = d.copy() –

0

En términos de rendimiento, hay una sobrecarga para llamar al list() en comparación con el corte. Entonces, para listas cortas, lst2 = lst1[:] es aproximadamente el doble de rápido que lst2 = list(lst1).

En la mayoría de los casos, esto probablemente se ve superado por el hecho de que list() es más legible, pero en bucles ajustados puede ser una optimización valiosa.

3

Las listas cortas, [:] es la mejor:

In [1]: l = range(10) 

In [2]: %timeit list(l) 
1000000 loops, best of 3: 477 ns per loop 

In [3]: %timeit l[:] 
1000000 loops, best of 3: 236 ns per loop 

In [6]: %timeit copy(l) 
1000000 loops, best of 3: 1.43 us per loop 

Para listas más grandes, que está sobre todos lo mismo:

In [7]: l = range(50000) 

In [8]: %timeit list(l) 
1000 loops, best of 3: 261 us per loop 

In [9]: %timeit l[:] 
1000 loops, best of 3: 261 us per loop 

In [10]: %timeit copy(l) 
1000 loops, best of 3: 248 us per loop 

Para listas muy grandes (Probé 50MM), todavía son más o menos lo mismo.

+0

No me molestaría si tengo que hacer una sola copia entre 100s de líneas de código. Solo si es una parte central de la aplicación y la copia de la lista es frecuente, podría molestarme. – Saurabh

Cuestiones relacionadas