2011-08-11 16 views
8

Me pidieron esto para una prueba de codificación y no sabía la respuesta. ¿Alguien tiene alguna idea?Diferencia entre a [:] = b y a = b [:]? (Python)

+0

posible duplicado de [¿Cuál es la diferencia entre la lista y la lista \ [: \] en python?] (Http://stackoverflow.com/questions/4081561/what-is-the-difference-between-list-and -list-in-python) –

+1

@Ignacio: No, esto no es un duplicado - esa pregunta no menciona el constructo 'a [:] = b'. –

+0

@ Adam: ¿Ni siquiera la parte que comienza "Al asignar ..."? –

Respuesta

8

[:] es el operador de sector.

Cuando está en el lado izquierdo, sobrescribe el contenido de la lista sin crear una nueva referencia.

Cuando está en el lado derecho, crea una copia de la lista con los mismos contenidos.

+0

Ohhh vale, tiene sentido ahora. Para aclarar, id (a) no cambia al hacer a [:] = b. id (a) cambia al hacer a = b [:]. ¿Hay alguna razón por la cual uno puede ser mejor que el otro? – user701632

+0

Sí, lo tienes exactamente. Si 'c' también se refiere a la misma lista que' a', entonces puede querer cambiar los contenidos, de modo que ambas variables se refieran a la lista actualizada. – recursive

1

En ambos casos, usted termina la lista a siendo una copia de la lista b. Pero el método utilizado para lograr esto ha cambiado.

a[:] = b modifica la lista a de modo que tenga los mismos elementos que b

a = b[:] produce una nueva lista, que es una copia de b y sustituye la lista a

La diferencia es si hemos modificado una lista existente o creado una nueva.

para ver la diferencia:

a = range(3) 
b = range(4) 
c = a # c and a now share the same list 
a[:] = b 
print "a", a 
print "b", b 
print "C", c 

las tres listas se imprimirán la misma. C y una parte del mismo objeto, así que cuando a se modificó así fue c

a = range(3) 
b = range(4) 
c = a # c and a now share the same list 
a = b[:] 
print "a", a 
print "b", b 
print "C", c 

Ahora c no se imprimirá el mismo que a. Después de la asignación, a y c no compartieron el mismo objeto.

Speedwise, a[:] = b' is probably a little faster then a = b [:] `. El primer formulario no tiene que crear un nuevo objeto de lista, simplemente puede modificar la lista existente. Una gran parte de esto es que puede reutilizar la memoria que ya posee la lista en lugar de asignar nueva memoria.

2

a = b[:] llamadas ya sea __getslice__ o en __getitem__b y asigna el resultado a a. En casi todos los casos (por ejemplo, listas, tuplas y otros tipos de secuencias), esto hace una copia superficial de la secuencia; No conozco ninguna clase que no implemente ese comportamiento, pero podría tener un tipo definido por el usuario que hiciera algo diferente. Cualquier otro objeto que anteriormente se refirió al valor anterior de a continuará refiriéndose a ese valor anterior.

a[:] = b, por el contrario, pide __setslice__ o __setitem__ para sustituir un subconjunto de los elementos de a con las de la secuencia b. En este caso, si el tipo de secuencia de a se comporta bien, esto reemplazará la totalidad de a, ya que el rango : sin puntos finales indica la secuencia completa. La diferencia aquí es que los tipos inmutables, como las tuplas, no le permitirán realizar __setslice__ (por ejemplo, lanzando una excepción TypeError). Cualquier otro objeto que anteriormente se refirió a a también se actualizará, ya que el objeto subyacente se está modificando.

Para los tipos mutables como list, el resultado de a = b[:] será idéntica a a[:] = b, en que a será una copia superficial de b; para tipos inmutables como tuple, a[:] = b no es válido. Para los tipos definidos por el usuario con mal comportamiento, todas las apuestas están desactivadas. También hay una diferencia en lo que sucede con otros objetos que se refieren al mismo objeto como a - con a = b[:], se refieren al valor original (a), pero con a[:] = b, se refieren al objeto modificado (copia superficial de b).

Cuestiones relacionadas