Python: lista de listas

Ejecutando el codigo

listoflists = [] list = [] for i in range(0,10): list.append(i) if len(list)>3: list.remove(list[0]) listoflists.append((list, list[0])) print listoflists 

devoluciones

 [([7, 8, 9], 0), ([7, 8, 9], 0), ([7, 8, 9], 0), ([7, 8, 9], 1), ([7, 8, 9], 2), ([7, 8, 9], 3), ([7, 8, 9], 4), ([7, 8, 9], 5), ([7, 8, 9], 6), ([7, 8, 9], 7)] 

así, de alguna manera, el primer argumento de cada tupla (lista) se actualiza cada vez en la lista de listas, pero la segunda lista de argumentos [0] no lo está. ¿Alguien puede explicar lo que está pasando aquí y sugerir una manera de solucionar esto? Me gustaría dar salida

 [([0],0), ([0,1],0), ... 

Las listas son de tipo mutable: para crear una copia (en lugar de pasar la misma lista), debe hacerlo explícitamente:

  listoflists.append((list[:], list[0])) 

Sin embargo, list ya es el nombre de un Python incorporado, sería mejor no usar ese nombre para su variable. Aquí hay una versión que no usa list como nombre de variable y hace una copia:

 listoflists = [] a_list = [] for i in range(0,10): a_list.append(i) if len(a_list)>3: a_list.remove(a_list[0]) listoflists.append((list(a_list), a_list[0])) print listoflists 

Tenga en cuenta que he demostrado dos formas diferentes de hacer una copia de una lista de arriba: [:] y list() .

El primero, [:] , es crear un sector (que normalmente se usa para obtener solo una parte de una lista), que contiene toda la lista y, por lo tanto, es efectivamente una copia de la lista.

El segundo, list() , utiliza el constructor de tipo de list real para crear una nueva lista que tenga un contenido igual a la primera lista. (No lo usé en el primer ejemplo porque estaba sobreescribiendo ese nombre en su código, ¡es un buen ejemplo de por qué no quiere hacer eso!)

En primer lugar, le recomiendo que cambie el nombre de su list variables a otra cosa. list es el nombre del constructor de listas integrado, y está ocultando su función normal. Voy a cambiar el nombre de la list a la siguiente.

Los nombres de Python son referencias que están vinculadas a objetos. Eso significa que, a menos que cree más de una lista, siempre que use a se refiera al mismo objeto de lista real que la última vez. Así que cuando llamas

 listoflists.append((a, a[0])) 

luego puede cambiar a y cambia a lo que apunta el primer elemento de esa tupla. Esto no ocurre con a[0] porque el objeto (que es un número entero) apuntado por a[0] no cambia (aunque a[0] apunta a objetos diferentes durante la ejecución de su código).

Puede crear una copia de la lista completa utilizando el constructor de list :

 listoflists.append((list(a), a[0])) 

O bien, puede utilizar la notación de división para hacer una copia:

 listoflists.append((a[:], a[0])) 

Vine aquí porque soy nuevo con python y flojo, así que estaba buscando un ejemplo para crear una lista de 2 listas, después de un tiempo me di cuenta de que el tema aquí podría estar mal … este es un código para crear una lista de listas :

 listoflists = [] for i in range(0,2): sublist = [] for j in range(0,10) sublist.append((i,j)) listoflists.append(sublist) print listoflists 

esta es la salida [[(0, 0), (0, 1), (0, 2), (0, 3), (0, 4), (0, 5), (0, 6), (0, 7), (0, 8), (0, 9)], [(1, 0), (1, 1), (1, 2), (1, 3), (1, 4), (1, 5), (1, 6), (1, 7), (1, 8), (1, 9)]]

El problema con su código parece ser que está creando una tupla con su lista y obtiene la referencia a la lista en lugar de una copia. Que supongo que debería caer bajo un tema tupla …

La variable de lista (que recomendaría cambiar de nombre a algo más sensible) es una referencia a un objeto de lista, que se puede cambiar.

En la línea

 listoflists.append((list, list[0])) 

En realidad, solo está agregando una referencia a la referencia de objeto por la variable de lista. Tiene múltiples posibilidades para crear una copia de la lista, por lo que listoflists contiene los valores que parece que espera:

Usa la biblioteca de copias

 import copy listoflists.append((copy.copy(list), list[0])) 

usa la notación de corte

 listoflists.append((list[:], list[0])) 

Cuando ejecutas el codigo

 listoflists.append((list, list[0])) 

No está (como creo que espera) agregando una copia de la list al final de las listoflists de listoflists . Lo que está haciendo es agregar una referencia a la list al final de las listoflists de listoflists . Por lo tanto, cada vez que actualice la list , se actualizarán todas las referencias a la list , que en este caso son todos los elementos de las listoflists de listoflists

Lo que podrías hacer en cambio es algo como esto:

 listoflists = [] for i in range(1, 10): listoflists.append((range(i), 0)) 

Tampoco va a obtener la salida que espera mientras agregue a las listas de listas solo dentro de la cláusula if.

Intenta algo como esto en su lugar:

 import copy listoflists = [] list = [] for i in range(0,10): list.append(i) if len(list)>3: list.remove(list[0]) listoflists.append((copy.copy(list), copy.copy(list[0]))) print(listoflists) 

Viajero del tiempo aquí

 List_of_list =[([z for z in range(x-2,x+1) if z >= 0],y) for y in range(10) for x in range(10)] 

Esto debería funcionar. Y la salida es esta:

 [([0], 0), ([0, 1], 0), ([0, 1, 2], 0), ([1, 2, 3], 0), ([2, 3, 4], 0), ([3, 4, 5], 0), ([4, 5, 6], 0), ([5, 6, 7], 0), ([6, 7, 8], 0), ([7, 8, 9], 0), ([0], 1), ([0, 1], 1), ([0, 1, 2], 1), ([1, 2, 3], 1), ([2, 3, 4], 1), ([3, 4, 5], 1), ([4, 5, 6], 1), ([5, 6, 7], 1), ([6, 7, 8], 1), ([7, 8, 9], 1), ([0], 2), ([0, 1], 2), ([0, 1, 2], 2), ([1, 2, 3], 2), ([2, 3, 4], 2), ([3, 4, 5], 2), ([4, 5, 6], 2), ([5, 6, 7], 2), ([6, 7, 8], 2), ([7, 8, 9], 2), ([0], 3), ([0, 1], 3), ([0, 1, 2], 3), ([1, 2, 3], 3), ([2, 3, 4], 3), ([3, 4, 5], 3), ([4, 5, 6], 3), ([5, 6, 7], 3), ([6, 7, 8], 3), ([7, 8, 9], 3), ([0], 4), ([0, 1], 4), ([0, 1, 2], 4), ([1, 2, 3], 4), ([2, 3, 4], 4), ([3, 4, 5], 4), ([4, 5, 6], 4), ([5, 6, 7], 4), ([6, 7, 8], 4), ([7, 8, 9], 4), ([0], 5), ([0, 1], 5), ([0, 1, 2], 5), ([1, 2, 3], 5), ([2, 3, 4], 5), ([3, 4, 5], 5), ([4, 5, 6], 5), ([5, 6, 7], 5), ([6, 7, 8], 5), ([7, 8, 9], 5), ([0], 6), ([0, 1], 6), ([0, 1, 2], 6), ([1, 2, 3], 6), ([2, 3, 4], 6), ([3, 4, 5], 6), ([4, 5, 6], 6), ([5, 6, 7], 6), ([6, 7, 8], 6), ([7, 8, 9], 6), ([0], 7), ([0, 1], 7), ([0, 1, 2], 7), ([1, 2, 3], 7), ([2, 3, 4], 7), ([3, 4, 5], 7), ([4, 5, 6], 7), ([5, 6, 7], 7), ([6, 7, 8], 7), ([7, 8, 9], 7), ([0], 8), ([0, 1], 8), ([0, 1, 2], 8), ([1, 2, 3], 8), ([2, 3, 4], 8), ([3, 4, 5], 8), ([4, 5, 6], 8), ([5, 6, 7], 8), ([6, 7, 8], 8), ([7, 8, 9], 8), ([0], 9), ([0, 1], 9), ([0, 1, 2], 9), ([1, 2, 3], 9), ([2, 3, 4], 9), ([3, 4, 5], 9), ([4, 5, 6], 9), ([5, 6, 7], 9), ([6, 7, 8], 9), ([7, 8, 9], 9)] 

Esto se hace mediante la comprensión de la lista (lo que hace que los elementos de bucle en una lista a través de un código de línea sea posible). La lógica detrás de este código de una línea es la siguiente:

(1) para x en el rango (10) y para y en el rango (10) se emplean para dos bucles independientes dentro de una lista

(2) (una lista, y) es el término general del bucle, por lo que se coloca antes de dos for en (1)

(3) la longitud de la lista en (2) no puede exceder de 3, y la lista depende de x, por lo que

 [z for z in range(x-2,x+1)] 

es usado

(4) porque z comienza desde cero pero el rango (x-2, x + 1) comienza desde -2, que no es lo que queremos, por lo que una statement condicional si z> = 0 se coloca al final de la lista en ( 2)

 [z for z in range(x-2,x+1) if z >= 0]