Estou iniciando python e estou tentando usar uma lista bidimensional, que inicialmente preenchei com a mesma variável em todos os lugares. Eu vim com isso:
def initialize_twodlist(foo):
twod_list = []
new = []
for i in range (0, 10):
for j in range (0, 10):
new.append(foo)
twod_list.append(new)
new = []
Ele fornece o resultado desejado, mas parece uma solução alternativa. Existe uma maneira mais fácil / mais curta / mais elegante de fazer isso?
python
multidimensional-array
thepandaatemyface
fonte
fonte
Respostas:
Um padrão que muitas vezes surgiu em Python foi
que ajudou a motivar a introdução de compreensões de lista, que convertem esse snippet em
que é mais curto e às vezes mais claro. Geralmente, você tem o hábito de reconhecê-las e frequentemente substituir loops por compreensões.
Seu código segue esse padrão duas vezes
fonte
[foo] * 10
é uma lista com as mesmas exatasfoo
10 vezes, o que pode ou não ser importante.[foo] * 10
: Isto significa que este não iria funcionar se você está preenchendo uma matriz com números aleatórios (avalia[random.randint(1,2)] * 10
a[1] * 10
ou[2] * 10
que significa que você começa uma matriz de todos 1s ou 2s, em vez de uma matriz aleatória.Você pode usar uma compreensão de lista :
fonte
i
para linhas ej
colunas, acho que deve ser melhor trocari
ej
na sua sintaxe para melhor compreensão e alterar o intervalo para 2 números diferentes.Não use
[[v]*n]*n
, é uma armadilha!mas
funciona bem.
fonte
*
está copiandoaddress
o objeto (lista).[[0] * col for _ in range(row)]
.Dessa maneira, é mais rápido que as compreensões de lista aninhadas
Aqui estão alguns horários do python3, para listas pequenas e grandes
Explicação:
[[foo]*10]*10
cria uma lista do mesmo objeto repetida 10 vezes. Você não pode simplesmente usar isso, porque modificar um elemento modificará o mesmo elemento em cada linha!x[:]
é equivalente a,list(X)
mas é um pouco mais eficiente, pois evita a pesquisa de nome. De qualquer maneira, ele cria uma cópia superficial de cada linha; portanto, agora todos os elementos são independentes.Todos os elementos são o mesmo
foo
objeto; portanto, sefoo
é mutável , você não pode usar esse esquema.ou assumindo uma classe (ou função)
Foo
que retornafoo
sfonte
copy.deepcopy
. Você precisa de um plano específico para seus dados se tiver um objeto mutável arbitrário.x
ey
. Não deveria ser[[copy.deepcopy(foo) for y in range(10)] for x in range(10)]
[foo]*10
não cria 10 objetos diferentes - mas é fácil ignorar a diferença no caso de foo ser imutável, como umint
oustr
.Para inicializar uma matriz bidimensional em Python:
fonte
a = [[0 for x in range(columns)] for y in range(rows)]
.fonte
[[0] * col] * row
não faz o que você quer é porque, quando você inicializa uma lista 2D dessa maneira, o Python não cria cópias distintas de cada linha. Em vez disso, iniciará a lista externa com ponteiros para a mesma cópia de[0]*col
. Qualquer edição que você fizer em uma das linhas será refletida nas linhas restantes, pois na verdade elas estão apontando para os mesmos dados na memória.Geralmente, quando você deseja matrizes multidimensionais, não deseja uma lista de listas, mas sim uma matriz numpy ou, possivelmente, um ditado.
Por exemplo, com numpy você faria algo como
fonte
numpy
seja ótimo, acho que pode ser um pouco exagerado para um iniciante.numpy
. 1Você pode fazer exatamente isso:
Por exemplo:
Mas isso tem um efeito colateral indesejado:
fonte
pois n é o número de linhas e m é o número de colunas e foo é o valor.
fonte
Se for uma matriz pouco povoada, é melhor usar um dicionário digitado com uma tupla:
fonte
para cada elemento, um novo
[0]*10
será criado.fonte
Abordagem incorreta: [[Nenhum * m] * n]
Com essa abordagem, o python não permite a criação de espaço de endereço diferente para as colunas externas e levará a vários comportamentos inadequados que a sua expectativa.
Abordagem correta, mas com exceção:
É uma boa abordagem, mas há exceção se você definir o valor padrão como
None
Portanto, defina seu valor padrão corretamente usando essa abordagem.
Absoluto correto:
Siga a resposta do microfone de loop duplo .
fonte
fonte
Para inicializar uma matriz bidimensional, use:
arr = [[]*m for i in range(n)]
na verdade,
arr = [[]*m]*n
criará uma matriz 2D na qual todas as n matrizes apontarão para a mesma matriz, portanto, qualquer alteração no valor em qualquer elemento será refletida em todas as n listaspara mais explicações, visite: https://www.geeksforgeeks.org/python-using-2d-arrays-lists-the-right-way/
fonte
use o pensamento mais simples para criar isso.
e adicione o tamanho:
ou se quisermos declarar o tamanho em primeiro lugar. nós usamos apenas:
fonte
Como @Arnab e @Mike apontaram, uma matriz não é uma lista. Poucas diferenças são 1) matrizes com tamanho fixo durante a inicialização 2) matrizes normalmente suportam operações menores que uma lista.
Talvez um exagero na maioria dos casos, mas aqui está uma implementação básica da matriz 2D que aproveita a implementação da matriz de hardware usando ctypes python (bibliotecas c)
fonte
O importante que entendi é: Ao inicializar uma matriz (em qualquer dimensão), devemos atribuir um valor padrão a todas as posições da matriz. Somente a inicialização é concluída. Depois disso, podemos alterar ou receber novos valores para qualquer posição da matriz. O código abaixo funcionou perfeitamente para mim
fonte
Se você usa o numpy , pode criar facilmente matrizes 2D:
x
fonte
O exemplo acima fornece uma matriz 2D de 5x5
Está usando compreensão de lista aninhada. Repartição como abaixo:
[x] * col -> expressão final avaliada
para x em -> x será o valor fornecido pelo iterador
[b para b no intervalo (linha)]] -> iterador.
[b para b no intervalo (linha)]] isso será avaliado para [0,1,2,3,4], pois linha = 5
, agora simplifica a
Isso será avaliado em [[0] * 5 para x em [0,1,2,3,4]] -> com x = 0 1ª iteração
[[1] * 5 para x em [0,1,2, 3,4]] -> com x = 1 2ª iteração
[[2] * 5 para x em [0,1,2,3,4]] -> com x = 2 3ª iteração
[[3] * 5 para x em [0,1,2,3,4]] -> com x = 3 4ª iteração
[[4] * 5 para x em [0,1,2,3,4]] -> com x = 4 5a iteração
fonte
Este é o melhor que eu encontrei para ensinar novos programadores e sem usar bibliotecas adicionais. Eu gostaria de algo melhor.
fonte
Aqui está uma maneira mais fácil:
Para inicializar todas as células com qualquer valor 'x', use:
fonte
Muitas vezes eu uso essa abordagem para inicializar uma matriz bidimensional
n=[[int(x) for x in input().split()] for i in range(int(input())]
fonte
O padrão geral para adicionar dimensões pode ser desenhado a partir desta série:
fonte
Você pode tentar isso [[0] * 10] * 10. Isso retornará a matriz 2D de 10 linhas e 10 colunas com o valor 0 para cada célula.
fonte
a = [[0]*10]*10
e, em seguida,a[0][0] = 1
você vai ver que primeiro elemento em cada linha agora igual a 1lst = [[0] * m para i no intervalo (n)]
inicialize todas as matrizes n = linhas e m = colunas
fonte
Outra maneira é usar um dicionário para armazenar uma matriz bidimensional.
Isso pode conter apenas valores 1D, 2D e, para inicializar esse valor
0
ou qualquer outro valor int, use coleções .fonte
Código:
initial_val
deve ser imutável.fonte
fonte