2011-05-06 8 views
5

Mi pregunta está relacionada con el siguiente bucle:comprensión de bucles con referencia a la lista de contenedores pitón

x=[[1,2,3],[4,5,6]] 
for v in x: 
    v=[0,0,0] 

aquí si imprime x se obtiene [[1,2,3], [4,5, 6]] ... por lo que v cambiado no es realmente una referencia a la lista en x. Pero cuando se hace algo como lo siguiente:

x=[[1,2,3],[4,5,6]] 
for v in x: 
    v[0]=0; v[1]=0; v[2] =0 

entonces obtendrá como x [[0,0,0], [0,0,0]]. Esta un poco difícil si se pone dentro de la lista x es bastante larga, e incluso hacer algo como esto:

x=[[1,2,3],[4,5,6]] 
for v in x: 
    for i in v: 
    i = 0 

me dará como x [[1,2,3], [4,5,6]]. Mi mejor opción es usar para i en xrange (0,3): v [i] = 0 .. Aunque todavía me gustaría saber qué está pasando aquí y cuáles son las otras alternativas cuando tengo una lista de listas o más listas anidadas.

Respuesta

7

Cuando pitón ejecuta v = [0, 0, 0], es

  1. Creación de un nuevo objeto de lista con tres ceros en el mismo.
  2. Asignación de una referencia a la nueva lista a una etiqueta llamada v

No importa si v era una referencia a otra cosa antes.

Si desea cambiar el contenido de la lista a la que hace referencia actualmente v, no puede usar la sintaxis v =. Debe asignarle elementos, como lo mencionó, o usar la notación de división v[:] = según lo observado por Sven.

+2

Esta es una respuesta mejor que Sven porque intenta explicar un poco de lo que está sucediendo, en lugar de simplemente dar una receta para ser seguido a ciegas. (Al menos, eso es todo lo que veo ahora en Sven, quizás lo editará). –

+0

Gracias por la explicación hasta el momento. Entonces, podemos mutar el elemento de lista que 'v' señala en el cuerpo del bucle, usando' v [:] = ... ', porque este elemento de lista ** es una lista en sí misma **. Ahora, si solo fuera un número entero o algo más que una lista, ¿hay alguna manera de mutarlo sin cambiar el encabezado del bucle? –

+0

@ Jan-PhilipGehrcke: algunos tipos, como int, son inmutables. Eso significa que una instancia de ese tipo nunca puede cambiar su valor. Los tipos inmutables comunes son tipos numéricos, cadenas y tuplas. – recursive

6
x = [[1,2,3],[4,5,6]] 
for v in x: 
    v[:] = [0,0,0] 

deberían hacer el truco.

+0

Niza :) ... Pensé que si tengo _x = [[1,2,3], [4,5,6]]; x = [x, x] _ .. luego -i puede usar el mismo enfoque al final de mi lista anidada ... así: _for v en x: para i en v: i [:] = [0,0, 0] _ – Jose

+0

@usuario: tenga cuidado. Cuando dice 'x = [x, x]', los dos elementos en la nueva lista tienen la misma identidad, por lo que cualquier cambio que realice en uno, afectará al otro. (de hecho, solo hay uno) – recursive

+0

lo siento, quise decir 'x = [x [:], x [:]]'. Fui perezoso al crear la lista de la lista de enteros – Jose

Cuestiones relacionadas