Python: lista de listas
a executar o código
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
O Devolve
[([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)]
de alguma forma, o primeiro argumento de cada tupla (lista) está sendo atualizado cada vez na lista de listas, mas a segunda lista de argumentos[0] não é. Alguém pode explicar o que se passa aqui e sugerir uma forma de resolver isto? Eu gostaria de sair
[([0],0), ([0,1],0), ...
7 answers
Listas são um tipo mutável - a fim de criar uma cópia( em vez de apenas passar a mesma lista ao redor), você precisa fazer isso explicitamente:
listoflists.append((list[:], list[0]))
No entanto, list
já é o nome de uma Python built-in-seria melhor não usar esse nome para a sua variável. Aqui está uma versão que não usa list
como nome de variável, e faz uma cópia:
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
Note que eu demonstrei duas maneiras diferentes de fazer uma cópia de uma lista acima: [:]
e list()
.
A primeiro, [:]
, está a criar uma fatia (normalmente usada para obter apenas parte de uma lista), que por acaso contém a lista inteira, e, portanto, é efectivamente uma cópia da lista.
O segundo, list()
, está a usar o list
type constructor para criar uma nova lista que tenha um conteúdo igual à primeira lista. (Eu não o usei no primeiro exemplo porque você estava sobrepondo esse nome em seu código-que é um bom exemplo de porque você não quer fazer isso!)
list
é o nome do construtor de listas embutido, e está a esconder a sua função normal. Vou mudar o nome list
para a
no seguinte.
Os nomes em Python são referências que estão ligadas a objectos. Isso significa que a menos que você crie mais de uma lista, sempre que você usa a
Ele está se referindo ao mesmo objeto de Lista real como da última vez. Por isso, quando ligares ...
listoflists.append((a, a[0]))
Podes mais tarde muda a
e muda o que o primeiro elemento dessa tupla aponta. Isto não acontece com a[0]
porque o objecto (que é um inteiro) apontado por a[0]
não muda (embora a[0]
aponte para objectos diferentes durante a execução do seu código).
Você pode criar uma cópia de toda a lista a
Usando o list
construtor:
listoflists.append((list(a), a[0]))
Ou, pode usar a notação para fazer uma cópia:
listoflists.append((a[:], a[0]))
Eu vim aqui porque sou novo com python e preguiçoso então eu estava procurando um exemplo para criar uma lista de 2 listas, depois de um tempo a percebeu que o tópico aqui pode estar errado... este é um código para criar uma 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
Este é o resultado [ [(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)] ]
O problema com o seu código parece ser você. estão a criar uma tupla com a sua lista e você recebe a referência à lista em vez de uma cópia. Acho que isso devia ser um tópico simples...A variável list (que eu recomendaria mudar o nome para algo mais sensível) é uma referência a um objecto de lista, que pode ser alterado.
Em linha
listoflists.append((list, list[0]))
Só está a adicionar uma referência à referência do objecto pela variável list. Você tem várias possibilidades de criar uma cópia da lista, então listoflists contém os valores que você parece esperar:
Usar a biblioteca de cópias
import copy
listoflists.append((copy.copy(list), list[0]))
Use o notação da fatia
listoflists.append((list[:], list[0]))
Quando se executa o código
listoflists.append((list, list[0]))
Você não está (como eu acho que você espera) adicionando uma cópia de list
ao final de listoflists
. O que você está fazendo é adicionar uma referência a list
ao final de listoflists
. Assim, cada vez que você atualizar list
, Ele atualiza cada referência a list
, que neste caso, é cada item em listoflists
listoflists = []
for i in range(1, 10):
listoflists.append((range(i), 0))
Você também não vai obter a saída que você está esperando desde que você adicione às listas apenas dentro da cláusula if.
Tente algo assim em vez disso: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)
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)]
Isto deve servir. E a saída é 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)]
Isto é feito pela compreensão da lista (o que torna os elementos em looping numa lista através de um código de linha possível). A lógica por trás deste código de uma linha é a seguinte:
(1) Para x na gama(10) e para y na gama(10) são utilizados dois loops independentes dentro de uma lista
(2) (uma lista, y) é o termo geral do laço, e é por isso que é colocado antes de dois for's em (1)
(3) o comprimento da lista em (2) não pode exceder 3, e a lista depende de x, então
[z for z in range(x-2,x+1)]
É utilizado
(4) porque z começa a partir de zero, mas o intervalo (x-2, x+1) começa a partir de -2 que não é o que queremos, por isso uma declaração condicional se z >= 0 é colocado no final da lista em (2)
[z for z in range(x-2,x+1) if z >= 0]