Pular para o conteúdo

Fundamentos

Matrizes em Python com listas de listas: linhas e colunas

Aprenda a criar, acessar e percorrer matrizes em Python com listas de listas, evite a armadilha do asterisco e veja usos reais na ESP32.

Por Prof. Rodrigo Faustino · Atualizado em · 19 min de leitura

Uma matriz é uma tabela de valores organizada em linhas e colunas. Em Python não existe um tipo próprio para ela: usa-se uma lista de listas, em que cada lista interna é uma linha. Para chegar a um valor, escrevem-se dois índices, m[i][j], o primeiro para a linha e o segundo para a coluna. Quase tudo o que você já sabe sobre listas continua valendo, e o que é novo se resume a duas coisas: percorrer a tabela com um laço dentro de outro e tomar cuidado com um erro clássico ao criar a matriz.

Matrizes aparecem sempre que os dados têm duas dimensões: o mapa de teclas de um teclado numérico, os pixels de um desenho numa tela, o tabuleiro de um jogo, as notas de vários alunos em várias provas, uma grade de LEDs. Este artigo mostra como criar, ler, alterar e percorrer uma matriz, como imprimi-la de forma legível, como somar linhas e colunas, onde está a armadilha do asterisco, e três usos que cabem na ESP32. Todos os exemplos foram executados no simulador, e os resultados citados são os que ele produz.

Uma lista de listas

Grade de 3 linhas e 4 colunas com os números de 1 a 12, cada célula com seus dois índices. A linha 1 está pintada de azul e o elemento da linha 1 e coluna 2, que vale 7, está destacado em laranja. À direita, uma lista mostra que len de m dá 3, len de m na posição 0 dá 4, m de 1 dá a lista 5, 6, 7, 8, m de 1 e 2 dá 7 e m de menos 1 e menos 1 dá 12.
Uma matriz é uma lista de listas. O primeiro índice escolhe a linha e o segundo escolhe a coluna.

Cada linha da matriz é uma lista comum, e a matriz é uma lista que guarda essas linhas:

m = [
    [1, 2, 3, 4],
    [5, 6, 7, 8],
    [9, 10, 11, 12]
]
print(m)
print(len(m), len(m[0]))
print(m[0], m[1][2], m[-1][-1], m[2][0])
print(m[1])
coluna = [linha[1] for linha in m]
print(coluna)
print(type(m), type(m[0]))
print("fim")

A saída é [[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]], depois 3 4, depois [1, 2, 3, 4] 7 12 9, depois [5, 6, 7, 8], depois [2, 6, 10], depois <class 'list'> <class 'list'> e por fim fim.

Vale ler cada linha com calma. O len(m) conta quantas linhas existem, porque m é a lista de fora. O len(m[0]) conta quantas colunas existem, porque m[0] é a primeira linha e o seu tamanho é o número de elementos dela. Os dois números juntos, 3 4, descrevem uma matriz de 3 linhas por 4 colunas.

O acesso funciona em dois passos. O m[1] devolve a linha de índice 1, que é a lista [5, 6, 7, 8]. Sobre essa lista, o [2] pega o elemento de índice 2, o 7. Por isso m[1][2] é só a escrita compacta de (m[1])[2]. Os índices negativos seguem a regra de sempre: m[-1] é a última linha e m[-1][-1] é o último elemento dela, o 12.

Existe uma assimetria que costuma surpreender. Pegar uma linha é fácil, é só m[1]. Pegar uma coluna não tem atalho, porque as colunas não existem como objetos: elas ficam espalhadas, um elemento em cada lista. Para juntá-las, percorre-se as linhas e tira-se o elemento da posição desejada, como na compreensão [linha[1] for linha in m], que devolve [2, 6, 10]. Esse recurso foi visto no artigo sobre operações com listas, e aqui ele ganha um bom motivo para existir.

Repare também que o type das duas respostas é list. Não há um objeto "matriz" por trás: é uma lista cujos elementos acontecem de ser listas. Isso explica tudo o que vem a seguir, inclusive os erros.

FastMindAssistente de IA local

A IA que lembra da sua vida e mora no seu computador

  • Memória de longo prazo com a fonte de cada resposta
  • Funciona offline: seus dados ficam no seu PC
  • Lê PDFs, slides, fotos e gravações de reunião
Baixar grátis para Windows

Plano Essencial grátis para sempre

Alterar um elemento

Como a lista é mutável, a matriz também é, e a atribuição usa os mesmos dois índices:

m = [[1, 2, 3], [4, 5, 6]]
m[0][1] = 99
m[1][2] += 10
print(m)
m[1] = [0, 0, 0]
print(m)
m[0].append(7)
print(m, len(m[0]), len(m[1]))
print("fim")

A saída é [[1, 99, 3], [4, 5, 16]], depois [[1, 99, 3], [0, 0, 0]], depois [[1, 99, 3, 7], [0, 0, 0]] 4 3 e por fim fim.

A primeira linha troca um elemento, a segunda soma 10 a outro. Na terceira, m[1] = [0, 0, 0] substitui uma linha inteira por outra lista. Na quarta, o append age sobre m[0], que é uma lista como outra qualquer, e acrescenta um elemento só àquela linha. O resultado é uma tabela em que as linhas têm tamanhos diferentes, o que o Python aceita sem reclamar. Voltaremos a isso mais adiante, porque uma matriz "de verdade" tem todas as linhas do mesmo tamanho, e quem garante isso é o programador, não a linguagem.

Percorrer com laços aninhados

Seis células de uma matriz de 2 linhas e 3 colunas numeradas de 1 a 6 na ordem em que um laço dentro de outro as visita. A primeira linha vai de 1 a 3 com setas para a direita, uma seta desce e volta ao início para a segunda linha, de 4 a 6. Ao lado, um quadro explica que o laço de dentro roda inteiro a cada volta do laço de fora, num total de 6 passos. Embaixo aparece a versão sem índices, com for linha in m e for valor in linha.
Dois laços aninhados percorrem a matriz linha a linha: o de fora escolhe a linha e o de dentro anda pelas colunas.

Para visitar todos os elementos, usa-se um laço dentro do outro. O de fora anda pelas linhas e o de dentro anda pelas colunas da linha atual:

m = [[1, 2, 3], [4, 5, 6]]
for linha in m:
    print(linha)
for linha in m:
    for valor in linha:
        print(valor, end=" ")
    print()
for i in range(len(m)):
    for j in range(len(m[i])):
        print(f"m[{i}][{j}] = {m[i][j]}")
for i, linha in enumerate(m):
    for j, valor in enumerate(linha):
        if valor % 2 == 0:
            print("par em", i, j)
print("fim")

A saída traz [1, 2, 3] e [4, 5, 6] do primeiro laço, depois as linhas 1 2 3 e 4 5 6 do segundo, depois seis linhas de m[0][0] = 1 até m[1][2] = 6, depois par em 0 1, par em 1 0 e par em 1 2, e por fim fim.

Os quatro laços fazem o mesmo percurso de jeitos diferentes, e cada um serve a um objetivo:

  • for linha in m entrega cada linha inteira, como lista. Serve quando o trabalho é por linha, como somar ou imprimir.
  • for linha in m com for valor in linha entrega cada valor, sem saber a posição. É o jeito mais limpo quando só o valor importa.
  • for i in range(len(m)) com for j in range(len(m[i])) dá os índices. É necessário quando a posição entra na conta, ou quando o programa vai alterar a matriz, já que o valor do laço é só uma cópia do número e mudá-lo não muda a matriz.
  • enumerate dá o índice e o valor ao mesmo tempo, sem precisar escrever m[i][j] toda vez.

O print(valor, end=" ") do segundo laço escreve os valores na mesma linha, separados por espaço. O print() vazio, no fim de cada volta do laço de fora, muda de linha. A posição desse print() é o detalhe que mais gera confusão: ele precisa ficar alinhado com o for valor, e não dentro dele. Dentro dele, cada número viria numa linha, e o resultado deixaria de parecer uma tabela. O artigo sobre o laço for com range e a explicação sobre por que repetir com laços ajudam a rever a mecânica do laço simples antes de empilhar dois.

A conta de custo é direta: com 2 linhas e 3 colunas, o laço de dentro roda 3 vezes para cada uma das 2 voltas do de fora, num total de 6 passos. Numa matriz de 100 por 100, são 10 mil. Para tabelas pequenas isso não pesa, mas é bom ter a noção de que o trabalho cresce com o produto das duas dimensões.

Mostrar a matriz como tabela

Imprimir a matriz com print(m) mostra os colchetes e as vírgulas, o que ajuda a depurar, mas não parece uma tabela. Para ver linhas e colunas alinhadas, imprime-se linha por linha:

m = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
for linha in m:
    print(*linha)
for linha in m:
    print(" ".join(str(v) for v in linha))
for linha in m:
    print("".join(f"{v:4d}" for v in linha))
print("fim")

A saída tem três blocos de três linhas. O primeiro e o segundo são iguais, 1 2 3, 4 5 6 e 7 8 9. O terceiro reserva 4 posições para cada número e fica 1 2 3, 4 5 6 e 7 8 9.

O print(*linha) é o mais curto: o asterisco desmancha a lista em argumentos separados, e o print os escreve com espaço entre eles. O join faz o mesmo, mas exige que cada item seja texto, daí o str(v). A f-string com {v:4d} dá uma largura fixa a cada número, o que alinha as colunas mesmo quando os valores têm quantidades diferentes de dígitos. Para tabelas com números de 1 e 2 dígitos misturados, é a que deixa o resultado mais bonito. O artigo sobre strings trata da formatação com mais detalhe e mostra o que o MicroPython não tem para alinhar texto.

FastTeacherPara professores

Da ementa ao semestre planejado

  • Plano de ensino e calendário montados sozinhos
  • Diário de aulas pronto para colar no SIGA
  • Slides e listas de exercícios com gabarito
Conhecer o FastTeacher

Versão Community grátis · Windows

Criar uma matriz sem ter os valores prontos

Às vezes a matriz não vem escrita à mão. O programa precisa criar uma de 5 por 5 cheia de zeros, ou uma tabuada, e preencher depois. Aqui mora a armadilha mais conhecida do assunto.

Dois quadros lado a lado. À esquerda, a expressão lista de zeros vezes 3, tudo vezes 2: os nomes m de 0 e m de 1 apontam para uma única linha, e depois de m de 0 e 0 receber 1 as duas linhas aparecem com 1, 0, 0 e a comparação is dá True. À direita, a compreensão com laço cria duas linhas separadas: só a primeira vira 1, 0, 0, a segunda continua 0, 0, 0 e a comparação is dá False.
O asterisco repete a mesma linha. Para linhas independentes, crie cada uma dentro de um laço.
errada = [[0] * 3] * 2
errada[0][0] = 1
print(errada, errada[0] is errada[1])
certa = [[0] * 3 for _ in range(2)]
certa[0][0] = 1
print(certa, certa[0] is certa[1])
tabuada = [[i * j for j in range(1, 4)] for i in range(1, 4)]
print(tabuada)
vazia = []
for i in range(2):
    linha = []
    for j in range(3):
        linha.append(0)
    vazia.append(linha)
print(vazia)
print("fim")

A saída é [[1, 0, 0], [1, 0, 0]] True, depois [[1, 0, 0], [0, 0, 0]] False, depois [[1, 2, 3], [2, 4, 6], [3, 6, 9]], depois [[0, 0, 0], [0, 0, 0]] e por fim fim.

Na primeira matriz, só uma posição foi alterada, mas duas mudaram. O motivo está no que o * faz. Em [0] * 3, a lista de três zeros é criada uma vez. Em [[0] * 3] * 2, o * 2 não cria duas listas: ele coloca a mesma lista em dois lugares. errada[0] e errada[1] são dois nomes para um único objeto, e o operador is confirma com True. Alterar uma linha altera "as duas", porque nunca existiram duas.

Com números, o * funciona sem problema, e é por isso que o erro engana: [0] * 3 é seguro, já que o 0 é imutável, e ninguém desconfia que [[0] * 3] * 2 seja diferente. A diferença só aparece quando o elemento repetido é mutável, e uma lista é. O artigo sobre listas mostrou a mesma ideia com b = a: dois nomes, um objeto.

A segunda forma, [[0] * 3 for _ in range(2)], resolve porque a expressão [0] * 3 é reavaliada a cada volta do laço, e cada volta cria uma lista nova. O False do is mostra que as duas linhas são objetos distintos. O _ é só um nome para a variável do laço que não será usada, por convenção. O resultado é uma matriz em que mudar uma linha deixa as outras em paz.

A terceira criação, a tabuada, mostra a compreensão com dois níveis. O laço de fora, for i in range(1, 4), cria cada linha, e o de dentro, for j in range(1, 4), cria os elementos dela. A leitura é: "para cada i, uma linha com i * j para cada j". A quarta, com append, faz a mesma coisa de forma explícita, e é a que costuma ser mais fácil de depurar quando a lógica da linha é comprida. As duas dão resultados equivalentes, e qualquer uma delas é uma forma correta de construir a matriz.

Copiar uma matriz

A mesma ideia explica o comportamento da cópia. O método copy() de uma lista de listas é superficial: copia a lista de fora, mas as linhas continuam sendo as mesmas:

a = [[1, 2], [3, 4]]
b = a.copy()
b[0][0] = 99
print(a, b)
print(a is b, a[0] is b[0])
c = [linha[:] for linha in a]
c[1][1] = 77
print(a)
print(c)
irregular = [[1], [2, 3], [4, 5, 6]]
print([len(linha) for linha in irregular])
print("fim")

A saída é [[99, 2], [3, 4]] [[99, 2], [3, 4]], depois False True, depois [[99, 2], [3, 4]], depois [[99, 2], [3, 77]], depois [1, 2, 3] e por fim fim.

O b = a.copy() criou uma lista nova, e por isso a is b dá False. Mas a primeira linha de a e a primeira linha de b são o mesmo objeto, o que o a[0] is b[0] confirma com True. Alterar b[0][0] mexeu, portanto, nas duas matrizes. A cópia profunda de uma matriz se faz copiando também cada linha: [linha[:] for linha in a], onde o linha[:] é a fatia que cria uma cópia de cada linha. Depois disso, mudar c[1][1] deixa a como estava.

A última parte do exemplo mostra uma lista de listas irregular, com linhas de 1, 2 e 3 elementos. O Python aceita sem problema, e é útil em alguns casos, como a lista de notas de cada aluno quando cada um fez uma quantidade diferente de provas. Mas quase todo código de matriz pressupõe que len(m[0]) vale para todas as linhas. Se o seu programa assume isso, convém garantir.

Somar linhas, colunas e o total

Com a matriz percorrida, as contas por linha e por coluna são direto da lista:

m = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
print(sum(m[0]), sum(m[1]))
print([sum(linha) for linha in m])
print([sum(linha[j] for linha in m) for j in range(len(m[0]))])
total = 0
for linha in m:
    total += sum(linha)
print(total)
print(max(max(linha) for linha in m), min(min(linha) for linha in m))
print("fim")

A saída é 6 15, depois [6, 15, 24], depois [12, 15, 18], depois 45, depois 9 1 e por fim fim.

A soma de uma linha é simples, porque ela já é uma lista: sum(m[0]). A de todas as linhas é uma compreensão que aplica o sum a cada uma. A das colunas pede mais cuidado, porque a coluna j precisa ser montada: para cada j, soma-se o elemento de posição j de todas as linhas, e o range(len(m[0])) dá os valores de j. O total pode ser calculado somando as somas das linhas, e o maior e o menor valor da matriz saem de um max sobre os máximos das linhas, e de um min sobre os mínimos.

Esse tipo de cálculo é a base dos desafios Soma da Matriz e Contador de Zeros, que pedem um laço aninhado com um acumulador e um contador. O Matriz Diagonal pede os elementos em que o índice da linha é igual ao da coluna, e a soma e a troca de linhas por colunas entre matrizes ficam para o próximo artigo.

Na ESP32: teclado, desenho e grade de LEDs

Três usos de matriz que cabem bem numa placa com poucos pinos:

from machine import Pin

TECLAS = [["1", "2", "3"], ["4", "5", "6"], ["7", "8", "9"], ["*", "0", "#"]]

def tecla(linha, coluna):
    return TECLAS[linha][coluna]

print(tecla(0, 0), tecla(2, 1), tecla(3, 2))

SETA = [
    [0, 0, 1, 0, 0],
    [0, 1, 1, 1, 0],
    [1, 0, 1, 0, 1],
    [0, 0, 1, 0, 0],
    [0, 0, 1, 0, 0]
]
for linha in SETA:
    print("".join("#" if v else "." for v in linha))

LEDS = [[Pin(18, Pin.OUT), Pin(19, Pin.OUT)], [Pin(21, Pin.OUT), Pin(22, Pin.OUT)]]
for linha in LEDS:
    for led in linha:
        led.value(0)
print(len(LEDS), len(LEDS[0]))
print("fim")

A saída é 1 8 #, depois cinco linhas, ..#.., .###., #.#.#, ..#.. e ..#.., depois 2 2 e por fim fim.

O teclado numérico de 4 linhas e 3 colunas é lido por varredura: o programa liga uma linha por vez, olha qual coluna responde e descobre a posição (linha, coluna) da tecla apertada. A matriz TECLAS traduz essa posição para o caractere, e a função tecla é só o acesso TECLAS[linha][coluna]. Sem a matriz, seria preciso um if para cada uma das 12 teclas.

O desenho de 5 por 5, a SETA, é um mapa de pixels: 1 acende, 0 apaga. O programa a percorre e troca cada valor por # ou ., o que mostra a imagem no console. Em um display de verdade, o mesmo laço acenderia pontos em vez de escrever caracteres, e o desenho ganha tamanho trocando só os números, sem mexer na lógica. O artigo sobre o display OLED e LCD mostra como levar um desenho assim para uma tela.

A grade de LEDs guarda os objetos Pin já organizados em linhas e colunas. Assim, acender o LED da linha 1 e coluna 0 é LEDS[1][0].value(1), e acender todos os de uma linha é um laço simples. O exemplo só prepara os pinos e apaga todos, para validar a estrutura. Num circuito real, os pinos dependem da ligação e do número de LEDs, e cada saída precisa do seu resistor, como mostra o artigo sobre PWM, LED e buzzer.

Erros comuns

O primeiro erro é pedir uma posição que não existe. Numa matriz 2 por 2, só os índices 0 e 1 valem, em qualquer dos dois níveis:

m = [[1, 2], [3, 4]]
print(m[2][0])
IndexError: list index out of range

O mesmo vale para m[0][5]: a linha existe, mas a coluna não. A mensagem é a mesma nos dois casos, e não diz qual dos dois índices falhou. Quem lê o erro precisa olhar a linha e conferir os tamanhos com len(m) e len(m[0]).

O segundo erro vem de quem usa a escrita de outras linguagens, com os dois índices dentro do mesmo colchete:

m = [[1, 2], [3, 4]]
print(m[0, 1])
TypeError: list indices must be integers, not tuple

O m[0, 1] é um índice só, e esse índice é a tupla (0, 1), que a lista não aceita. No Python de computador, o texto da mensagem é um pouco diferente, list indices must be integers or slices, not tuple, mas o erro e a correção são os mesmos: escreva m[0][1].

O terceiro é indexar um número como se fosse uma lista:

m = [[1, 2], [3, 4]]
print(m[0][0][0])
TypeError: 'int' object isn't subscriptable

Depois de m[0][0] já se chegou ao 1, que é um inteiro, e o terceiro [0] não tem onde entrar. O Python de computador escreve 'int' object is not subscriptable. Essa mensagem costuma indicar que o código foi escrito para uma matriz com mais níveis do que a que existe.

O quarto aparece quando a lista tem um elemento que não é lista. Se o programa faz m.append(5) e depois percorre com o laço aninhado, ele imprime 1 2 3 4 e para ao chegar no 5:

TypeError: 'int' object isn't iterable

O laço de dentro tenta percorrer o 5 como se fosse uma linha, e um número não se percorre. A mensagem do Python de computador diz 'int' object is not iterable. É o sinal de que uma linha foi substituída por um valor solto.

Dois comportamentos que não são erro, mas confundem: m[0] + m[1] junta as duas linhas numa lista só e dá [1, 2, 3, 4], e m[0] * 2 repete a linha e dá [1, 2, 1, 2]. O + e o * das listas não fazem conta de matriz elemento a elemento. Já m + 1 falha, com unsupported types for __add__: 'list', 'int' no simulador e can only concatenate list (not "int") to list no Python de computador. Somar duas matrizes de verdade exige um laço, e esse é o assunto do próximo artigo.

O que costuma aparecer em sala

Estes são os padrões que mais se repetem com quem aprende matrizes. Não são o relato de uma turma específica, e sim as dificuldades que aparecem sempre.

O [[0] * 3] * 2. É o campeão. A pessoa cria a matriz de zeros, altera um elemento, imprime e vê o valor repetido em outra linha. A reação típica é achar que o print está errado ou que o laço rodou duas vezes. O caminho de volta é o teste m[0] is m[1], que mostra de uma vez que as linhas são a mesma, seguido da troca pela compreensão com laço.

Trocar i e j. Escrever m[j][i] onde deveria ser m[i][j]. Numa matriz quadrada, o programa roda e entrega números errados, o que é pior do que parar com erro. Numa não quadrada, o IndexError aparece, e é ele que denuncia a troca. Um hábito que ajuda é dar nomes que lembrem a ordem, como lin e col, e escrever sempre a linha primeiro.

Confundir len(m) com len(m[0]). O primeiro é o número de linhas e o segundo, de colunas. Quem usa range(len(m)) nos dois laços funciona em matrizes quadradas e quebra nas outras. A regra é: o laço de fora usa len(m) e o de dentro usa len(m[i]).

Testar só com matriz 2 por 2. Uma matriz pequena e quadrada esconde quase todos os erros acima, porque i e j valem o mesmo intervalo e trocá-los não quebra nada. Testar com uma de 2 linhas por 3 colunas, ou de 3 por 2, descobre muito mais problema com o mesmo esforço.

O m[0, 1]. Vem de quem já programou em outra linguagem ou usou planilhas. O erro de tipo com a tupla se resolve rápido quando se enxerga que são dois colchetes, um para cada lista.

Imprimir a lista de listas crua. O resultado do print(m) é correto, mas ninguém consegue conferi-lo com os olhos numa matriz de 5 por 5. Imprimir linha por linha, com print(*linha), transforma a conferência em olhar uma tabela.

Esquecer de criar a linha. Em m[i][j] = valor sobre uma matriz vazia, o erro é de índice, porque as linhas ainda não existem. Ou se cria a matriz com o tamanho certo desde o início, ou se vai acrescentando cada linha com append antes de preencher.

Alterar a cópia rasa. Quem faz b = a.copy() e muda b descobre que a também mudou. O hábito a criar é perguntar, antes de copiar, se os elementos são listas.

Exercício: ler, somar e conferir uma matriz

Escreva um programa que leia o número de linhas, o de colunas e depois os valores, um por vez, monte a matriz, imprima-a como tabela e mostre a soma de cada linha, a soma de cada coluna e o total. A solução abaixo mostra um caminho, e o entradas= do bloco fornece os valores: 2 linhas, 3 colunas e os números de 1 a 6.

linhas = int(input())
colunas = int(input())
m = []
for i in range(linhas):
    linha = []
    for j in range(colunas):
        linha.append(int(input()))
    m.append(linha)
print("matriz", m)
for linha in m:
    print(*linha)
print("soma das linhas", [sum(linha) for linha in m])
print("soma das colunas", [sum(m[i][j] for i in range(linhas)) for j in range(colunas)])
total = 0
for linha in m:
    total += sum(linha)
print("total", total)
print("fim")

O simulador repete na saída os valores digitados, um por linha, e depois vem matriz [[1, 2, 3], [4, 5, 6]], depois 1 2 3, depois 4 5 6, depois soma das linhas [6, 15], depois soma das colunas [5, 7, 9], depois total 21 e por fim fim.

Repare em quatro decisões. A linha é criada dentro do laço de fora, e por isso cada volta tem a sua lista própria, o que evita a armadilha do asterisco. Cada valor passa por int(input()), já que o input devolve texto. Os números de linhas e de colunas são guardados em variáveis, e é o colunas que controla o laço de dentro, e não um valor fixo. E as colunas somam com m[i][j] varrendo o i, o que funciona porque o programa sabe quantas linhas há.

Para treinar além disso, tente: trocar as entradas para 3 linhas e 2 colunas e ver se tudo continua certo; acrescentar uma linha com o maior valor de cada linha; contar quantos elementos são pares; e imprimir a matriz com a largura de 4 posições por número.

Perguntas frequentes

O Python tem um tipo matriz? Não no núcleo da linguagem. A lista de listas é o jeito padrão. Em computadores, bibliotecas como o NumPy oferecem matrizes numéricas completas, mas elas não existem no simulador, e para tabelas pequenas a lista de listas resolve.

Como sei quantas linhas e colunas a matriz tem? O número de linhas é len(m), e o de colunas é len(m[0]), desde que a matriz não esteja vazia e todas as linhas tenham o mesmo tamanho. Com m = [], o len(m[0]) dá IndexError, porque não há primeira linha.

Por que a mudança em uma linha aparece em outra? Porque as duas linhas são o mesmo objeto, quase sempre por causa do [[0] * 3] * 2 ou de uma cópia superficial. O teste m[0] is m[1] confirma, e a criação com compreensão ou append num laço corrige.

Posso ter uma matriz de textos ou de valores misturados? Pode. A lista aceita qualquer coisa em cada posição, e o exemplo do teclado usa textos. Misturar tipos numa mesma matriz, porém, complica as contas, e só vale se o programa tratar cada caso.

Preciso mesmo de range(len(m)), ou posso usar for linha in m? Se só interessa o valor, o for direto é mais limpo. Se a posição importa, ou se a matriz será alterada durante o percurso, use os índices ou o enumerate.

Existe matriz com mais de duas dimensões? Existe: uma lista de listas de listas, acessada com m[i][j][k]. Funciona do mesmo jeito, só que com um nível a mais. Para a maioria dos programas de placa, duas dimensões bastam.

Para continuar

Os desafios Matriz Diagonal, Soma da Matriz e Contador de Zeros praticam o acesso por dois índices e o percurso com laços aninhados. Para rever o que sustenta este artigo, vale passar pelos textos sobre listas, operações com listas e tuplas, e pela trilha de lógica.

O próximo artigo continua com as matrizes: soma de duas matrizes, transposição, que troca linhas por colunas, e como pegar a diagonal principal e a secundária.

Para praticar no PyPlaca

Trilhas

Lições

Fichas de componentes

FastTeacherPara professores

Da ementa ao semestre planejado

  • Plano de ensino e calendário montados sozinhos
  • Diário de aulas pronto para colar no SIGA
  • Slides e listas de exercícios com gabarito
Conhecer o FastTeacher

Versão Community grátis · Windows

FastMindAssistente de IA local

A IA que lembra da sua vida e mora no seu computador

  • Memória de longo prazo com a fonte de cada resposta
  • Funciona offline: seus dados ficam no seu PC
  • Lê PDFs, slides, fotos e gravações de reunião
Baixar grátis para Windows

Plano Essencial grátis para sempre

FastTeacherPara professores

Da ementa ao semestre planejado

  • Plano de ensino e calendário montados sozinhos
  • Diário de aulas pronto para colar no SIGA
  • Slides e listas de exercícios com gabarito
Conhecer o FastTeacher

Versão Community grátis · Windows