¿Cuál es la mejor manera de copiar una lista? Sé de las siguientes maneras, ¿cuál es mejor? ¿O hay otra manera?¿Cuál es la mejor manera de copiar una lista?
lst = ['one', 2, 3]
lst1 = list(lst)
lst2 = lst[:]
import copy
lst3 = copy.copy(lst)
¿Cuál es la mejor manera de copiar una lista? Sé de las siguientes maneras, ¿cuál es mejor? ¿O hay otra manera?¿Cuál es la mejor manera de copiar una lista?
lst = ['one', 2, 3]
lst1 = list(lst)
lst2 = lst[:]
import copy
lst3 = copy.copy(lst)
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)
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]]
'copy()' no funcionará en el último caso, necesita 'deepcopy()' siempre que tenga una referencia dentro del objeto. –
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
También puede hacer esto:
import copy
list2 = copy.copy(list1)
Esto debería hacer lo mismo que la copia superficial de Mark Roddy.
También puede hacer:
a = [1, 2, 3]
b = list(a)
¿El resultado es una copia superficial o profunda? – minty
No, usar list() es definitivamente una copia superficial. Pruébalo. –
¿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? –
me gusta hacer:
lst2 = list(lst1)
La ventaja sobre lst1 [:] es que el mismo lenguaje que funciona para dicts:
dct2 = dict(dct1)
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 –
The un poco de información aquí es que para los diccionarios, puede hacer d = d.copy() –
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.
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.
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
¿Qué quiere decir con elementos no copiados? – sheats
Si los elementos son objetos mutables, se pasan por referencia, debe utilizar Deepcopy para copiarlos realmente. –
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. –