Pular para o conteúdo

Fundamentos

Operações com matrizes em Python: soma, transposição e diagonal

Some matrizes posição a posição, faça a transposta com laços ou zip, extraia as diagonais e teste a simetria, com exemplos para a ESP32.

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

Com a matriz já criada e percorrida, o passo seguinte é fazer contas com ela. Três operações aparecem o tempo todo e cobrem boa parte do que se pede em provas, exercícios e projetos: somar duas matrizes, transpor uma matriz, trocando linhas por colunas, e pegar as diagonais. As três se resolvem com o que o artigo anterior já mostrou, laços aninhados e compreensões, e cada uma ensina um cuidado novo: o tamanho precisa combinar, a ordem dos índices muda, e a diagonal só faz sentido numa matriz quadrada.

Um aviso antes de começar: o Python não faz conta de matriz com os operadores. O + entre duas listas as junta, o * entre duas listas dá erro, e nada disso se parece com a soma e o produto da matemática. Quem faz a conta é um laço que você escreve. Isso é uma boa notícia para o aprendizado, porque cada operação vira um exercício de pensar em índices, e para a ESP32, que não precisa carregar uma biblioteca numérica para tratar uma tabela pequena. Os exemplos rodaram no simulador, e os resultados citados são os dele.

Somar duas matrizes

Duas matrizes A e B de 2 linhas e 3 colunas somadas dando a matriz C. A tem os números de 1 a 6, B tem 10, 20, 30, 40, 50 e 60, e C tem 11, 22, 33, 44, 55 e 66. A posição da linha 1 e coluna 2 está em destaque nas três, mostrando 6 mais 60 igual a 66. Abaixo, a fórmula de C de i e j como A de i e j mais B de i e j, e um aviso em vermelho de que somar uma matriz 2 por 3 com uma 2 por 2 dá IndexError.
A soma de matrizes é feita posição a posição, e só vale para matrizes do mesmo tamanho.

Na soma de matrizes, cada posição de uma é somada com a mesma posição da outra, e o resultado vai para essa posição numa matriz nova. Por isso as duas precisam ter o mesmo número de linhas e de colunas.

a = [[1, 2, 3], [4, 5, 6]]
b = [[10, 20, 30], [40, 50, 60]]
soma = []
for i in range(len(a)):
    linha = []
    for j in range(len(a[0])):
        linha.append(a[i][j] + b[i][j])
    soma.append(linha)
print(soma)
soma2 = [[a[i][j] + b[i][j] for j in range(len(a[0]))] for i in range(len(a))]
print(soma2, soma == soma2)
soma3 = [[x + y for x, y in zip(la, lb)] for la, lb in zip(a, b)]
print(soma3)
print([[2 * v for v in linha] for linha in a])
print([[v - 1 for v in linha] for linha in b])
print(a + b)
dif = [[a[i][j] - b[i][j] for j in range(3)] for i in range(2)]
print(dif)
print("fim")

A saída é [[11, 22, 33], [44, 55, 66]], depois [[11, 22, 33], [44, 55, 66]] True, depois [[11, 22, 33], [44, 55, 66]], depois [[2, 4, 6], [8, 10, 12]], depois [[9, 19, 29], [39, 49, 59]], depois [[1, 2, 3], [4, 5, 6], [10, 20, 30], [40, 50, 60]], depois [[-9, -18, -27], [-36, -45, -54]] e por fim fim.

O primeiro bloco é a forma explícita. O laço de fora escolhe a linha i, o de dentro escolhe a coluna j, e cada soma a[i][j] + b[i][j] entra numa lista linha. Quando o laço de dentro termina, a linha pronta é acrescentada à soma. A linha é criada de novo a cada volta do laço de fora, e é isso que impede o erro do asterisco que o artigo anterior mostrou: cada linha do resultado é uma lista própria.

O segundo bloco é o mesmo laço escrito como compreensão de dois níveis, e a comparação soma == soma2 confirma que o resultado é igual. O terceiro troca os índices por zip, que emparelha as listas e entrega os elementos juntos. O zip(a, b) produz pares de linhas, (la, lb), e o zip(la, lb) dentro dele produz pares de números, (x, y). Não há índice nenhum, e a leitura fica próxima do que se diz em voz alta: "para cada par de linhas, some os pares de números". O custo é uma ressalva que veremos mais à frente, sobre o que o zip faz quando os tamanhos não combinam.

As linhas seguintes mostram as variações. Multiplicar a matriz por um número, o chamado produto por escalar, é uma compreensão que aplica 2 * v a cada valor. Subtrair um número de todos os elementos é a mesma ideia. A subtração de matrizes troca o + por - na fórmula da soma, e dá o resultado dif. E o que o a + b entrega? Uma lista com as quatro linhas, uma atrás da outra. Ele não soma nada: o + de listas é concatenação, como já aparecia no artigo sobre operações com listas, e aqui ele só empilha as linhas de b embaixo das de a.

A escolha entre as três formas é de estilo. A com índices é a mais fácil de depurar e a única que serve quando a posição entra na conta. A com zip é a mais curta, e a compreensão com índices fica no meio. Para quem está aprendendo, vale escrever a primeira e só depois migrar para as outras.

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

Transpor: trocar linhas por colunas

Uma matriz m de 2 linhas e 3 colunas com os números de 1 a 6 à esquerda e a transposta t de 3 linhas e 2 colunas à direita, ligadas por uma seta com o texto linhas viram colunas. A primeira linha 1, 2, 3 de m vira a primeira coluna de t e a segunda linha 4, 5, 6 vira a segunda coluna. O elemento 3 vai de m de 0 e 2 para t de 2 e 0. Abaixo estão as duas formas de escrever em Python, com compreensão e com zip.
A transposta troca linhas por colunas: o elemento m[i][j] vai parar em t[j][i].

A transposta de uma matriz é outra matriz em que as linhas viram colunas. O elemento que estava na linha i e coluna j passa para a linha j e coluna i. Uma matriz de 2 linhas por 3 colunas vira uma de 3 linhas por 2 colunas.

m = [[1, 2, 3], [4, 5, 6]]
t = []
for j in range(len(m[0])):
    linha = []
    for i in range(len(m)):
        linha.append(m[i][j])
    t.append(linha)
print(t)
t2 = [[m[i][j] for i in range(len(m))] for j in range(len(m[0]))]
print(t2, t == t2)
t3 = [list(c) for c in zip(*m)]
print(t3)
print(list(zip(*m)))
t4 = list(map(list, zip(*m)))
print(t4)
print(len(m), len(m[0]), len(t), len(t[0]))
tt = [[t[i][j] for i in range(len(t))] for j in range(len(t[0]))]
print(tt == m)
q = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
n = len(q)
for i in range(n):
    for j in range(i + 1, n):
        q[i][j], q[j][i] = q[j][i], q[i][j]
print(q)
r = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
for i in range(n):
    for j in range(n):
        r[i][j], r[j][i] = r[j][i], r[i][j]
print(r)
print("fim")

A saída é [[1, 4], [2, 5], [3, 6]], depois [[1, 4], [2, 5], [3, 6]] True, depois [[1, 4], [2, 5], [3, 6]], depois [(1, 4), (2, 5), (3, 6)], depois [[1, 4], [2, 5], [3, 6]], depois 2 3 3 2, depois True, depois [[1, 4, 7], [2, 5, 8], [3, 6, 9]], depois [[1, 2, 3], [4, 5, 6], [7, 8, 9]] e por fim fim.

Na primeira versão, os laços trocaram de papel em relação à soma. O de fora percorre as colunas de m, com range(len(m[0])), e cada volta monta uma linha nova de t pegando o elemento m[i][j] de todas as linhas i. Em outras palavras, a primeira linha de t é a primeira coluna de m. É exatamente a operação de "pegar uma coluna" que o artigo anterior fez com uma compreensão, repetida para todas as colunas. A segunda versão é a mesma coisa em duas linhas, e a comparação t == t2 dá True.

A terceira é o truque que se vê em código de Python: zip(*m). O asterisco antes do nome desmancha a lista em argumentos separados. Escrever zip(*m) com m = [[1, 2, 3], [4, 5, 6]] equivale a escrever zip([1, 2, 3], [4, 5, 6]), e o zip junta o primeiro elemento de cada linha, depois o segundo, depois o terceiro. Os grupos que ele entrega são (1, 4), (2, 5) e (3, 6), que são justamente as colunas. O quarto resultado do exemplo mostra que cada grupo é uma tupla, o tipo visto no artigo sobre tuplas e desempacotamento. Se a transposta precisa ser uma lista de listas, converte-se cada tupla com list(c), na compreensão, ou com map(list, ...), como na quinta saída.

Note o 2 3 3 2: a matriz m tem 2 linhas e 3 colunas, e t tem 3 linhas e 2 colunas. As dimensões se invertem, e é aqui que nasce o erro mais comum, que é escrever na transposta uma conta que supõe o tamanho original. E a linha tt == m mostra a propriedade mais bonita da operação: transpor duas vezes devolve a matriz de partida.

Transpor no lugar, só para matriz quadrada

Os dois últimos blocos mostram a transposição no lugar, sem criar matriz nova, numa matriz 3 por 3. A ideia é trocar q[i][j] com q[j][i] por meio de uma atribuição dupla, que é a troca de dois valores sem variável auxiliar. O primeiro, com j in range(i + 1, n), visita só os pares acima da diagonal, e cada par é trocado uma vez, o que dá a transposta certa. O segundo percorre a matriz inteira, com j in range(n), e o resultado é a matriz original sem mudança.

O motivo é que, no segundo, cada par é trocado duas vezes: uma ao visitar (i, j) e outra ao visitar (j, i). A segunda troca desfaz a primeira. É um erro que não dá mensagem nenhuma: o programa roda, imprime uma matriz bonita, e ela só não é a transposta. E o método só funciona se a matriz for quadrada. Numa matriz 2 por 3, o resultado nem tem o tamanho certo, já que a transposta ocupa 3 por 2 e não cabe nas mesmas listas. Para matrizes que não são quadradas, só vale criar uma matriz nova.

Diagonais, traço e simetria

Matriz 3 por 3 com os números de 1 a 9. A diagonal principal, 1, 5 e 9, está em azul e a diagonal secundária, 3, 5 e 7, está em verde, com o 5 central em laranja por pertencer às duas. Ao lado, as regras: na principal a linha é igual à coluna e a soma dá 15, chamada traço; na secundária linha mais coluna é igual a n menos 1 e a soma também dá 15. Aparecem ainda os elementos acima da principal, 2, 3 e 6, e abaixo, 4, 7 e 8.
As duas diagonais de uma matriz quadrada e os elementos acima e abaixo da principal.

Numa matriz quadrada, com o mesmo número de linhas e de colunas, existem duas diagonais. A principal vai do canto de cima à esquerda até o de baixo à direita, e nela o índice da linha é igual ao da coluna: i == j. A secundária vai do canto de cima à direita até o de baixo à esquerda, e nela i + j == n - 1, sendo n o tamanho da matriz.

m = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
n = len(m)
print([m[i][i] for i in range(n)])
print([m[i][n - 1 - i] for i in range(n)])
print(sum(m[i][i] for i in range(n)), sum(m[i][n - 1 - i] for i in range(n)))
for i in range(n):
    for j in range(n):
        if i == j:
            print("principal", m[i][j])
        elif i + j == n - 1:
            print("secundaria", m[i][j])
acima = [m[i][j] for i in range(n) for j in range(n) if j > i]
abaixo = [m[i][j] for i in range(n) for j in range(n) if j < i]
print(acima, abaixo)
ident = [[1 if i == j else 0 for j in range(4)] for i in range(4)]
for linha in ident:
    print(*linha)
s = [[1, 2, 3], [2, 5, 6], [3, 6, 9]]
simetrica = True
for i in range(n):
    for j in range(n):
        if s[i][j] != s[j][i]:
            simetrica = False
print(simetrica)
print(m == [list(c) for c in zip(*m)])
print(s == [list(c) for c in zip(*s)])
print("fim")

A saída é [1, 5, 9], depois [3, 5, 7], depois 15 15, depois cinco linhas, principal 1, secundaria 3, principal 5, secundaria 7 e principal 9, depois [2, 3, 6] [4, 7, 8], depois quatro linhas da identidade, 1 0 0 0, 0 1 0 0, 0 0 1 0 e 0 0 0 1, depois True, False, True e por fim fim.

A diagonal principal é a mais simples de extrair: [m[i][i] for i in range(n)], com um só índice, repetido nos dois lugares. A secundária usa n - 1 - i para a coluna, porque quando a linha sobe, a coluna desce. Numa matriz 3 por 3, a linha 0 usa a coluna 2, a linha 1 usa a 1, e a linha 2 usa a 0. A soma da diagonal principal tem nome próprio, o traço da matriz, e aqui as duas diagonais somam 15.

O laço com if e elif mostra um detalhe sobre o elemento central, o 5. Ele pertence às duas diagonais, já que 1 == 1 e 1 + 1 == 2. Como o if vem primeiro, o 5 é impresso como principal e o elif não chega a ser testado. Isso vale para toda matriz de tamanho ímpar. Numa de tamanho par, como a 2 por 2 do desafio Diagonal da Matriz, as diagonais não têm elemento comum.

As duas compreensões acima e abaixo pegam os triângulos da matriz: os elementos em que j > i ficam acima da diagonal principal, e os em que j < i ficam abaixo. Note que a compreensão tem dois for, escritos um depois do outro. A leitura é a mesma de dois laços aninhados, o de fora primeiro, e o if no fim filtra.

A matriz identidade, com 1 na diagonal e 0 no resto, nasce de uma compreensão de dois níveis com o teste 1 if i == j else 0. Ela aparece em muita conta de matriz, e é uma boa demonstração de que a diagonal é uma condição entre índices.

Por fim, a simetria. Uma matriz é simétrica quando é igual à sua transposta, ou seja, quando s[i][j] == s[j][i] para todas as posições. O primeiro teste, com laços, parte de True e vira False ao primeiro par diferente, o padrão de "bandeira": uma variável que começa verdadeira e que um teste pode derrubar. O segundo compara a matriz com a transposta feita por zip. O resultado é False para a m, que não é simétrica, e True para a s, que é.

Na ESP32: imagens, sensores e brilho

As três operações têm usos diretos em dados de placa:

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]
]
def mostrar(img):
    for linha in img:
        print("".join("#" if v else "." for v in linha))
mostrar(SETA)
print()
mostrar([list(c) for c in zip(*SETA)])
print()
mostrar([linha[::-1] for linha in SETA])
print()
mostrar(SETA[::-1])
print()
leituras = [[22.5, 60], [23.0, 58], [24.5, 55], [21.0, 62]]
medias = [sum(c) / len(c) for c in zip(*leituras)]
print(medias)
print([round(x, 1) for x in medias])
brilho = [[0, 100, 200], [50, 150, 250]]
mais = [[min(255, v + 80) for v in linha] for linha in brilho]
print(mais)
print("fim")

A saída tem cinco blocos de desenho separados por linhas em branco. O primeiro é a seta de sempre: ..#.., .###., #.#.#, ..#.. e ..#... O segundo é a transposta: ..#.., .#..., #####, .#... e ..#... O terceiro é o espelho horizontal, que fica igual por ser simétrico para a direita e a esquerda. O quarto é o espelho vertical: ..#.., ..#.., #.#.#, .###. e ..#... Depois vêm [22.75, 58.75], [22.8, 58.8], [[80, 180, 255], [130, 230, 255]] e fim.

O primeiro uso é manipular imagens. A mesma SETA do artigo anterior ganha novas versões com uma linha cada. A transposta reflete o desenho em torno da diagonal, o que o segundo bloco mostra com uma seta que virou outro desenho. O espelho horizontal inverte cada linha, com linha[::-1], e o vertical inverte a ordem das linhas, com SETA[::-1]. Uma observação sobre o simulador: a fatia com passo funciona em listas, como aqui, mas não em textos e tuplas, como visto no artigo sobre strings.

O segundo uso é estatística por coluna. Cada linha de leituras é uma medição, e cada coluna é um sensor: temperatura e umidade, por exemplo, lidas quatro vezes. O zip(*leituras) entrega os valores de cada sensor juntos, e a compreensão calcula a média de cada um, [22.75, 58.75]. O round arredonda para uma casa. O artigo sobre sensores DHT22, HC-SR04 e PIR mostra como obter essas leituras de verdade.

O terceiro uso é ajustar o brilho de uma imagem em tons de cinza, somando 80 a cada pixel e limitando o resultado a 255 com min, já que 255 é o máximo de uma saída de 8 bits. É uma operação por escalar, só que com um teto. O padrão min(255, ...) serve para qualquer valor que não pode passar de um limite, e o max(0, ...) faz o mesmo para o piso.

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

Erros comuns

O primeiro erro é somar matrizes de tamanhos diferentes. Se o laço usa as dimensões de uma e acessa a outra, falta posição:

a = [[1, 2, 3], [4, 5, 6]]
b = [[1, 2], [3, 4]]
soma = [[a[i][j] + b[i][j] for j in range(len(a[0]))] for i in range(len(a))]
print(soma)
IndexError: list index out of range

O programa falha ao chegar na coluna 2 de b, que não existe. O erro é bom, porque avisa. O perigo é o oposto: quando um laço usa as dimensões da menor, ele não falha e perde dados sem avisar. O mesmo vale para o zip, que para no menor:

a = [[1, 2, 3], [4, 5, 6]]
b = [[1, 2], [3, 4]]
print([[x + y for x, y in zip(la, lb)] for la, lb in zip(a, b)])
print(list(zip(*[[1, 2, 3], [4, 5]])))
print("fim")

A saída é [[2, 4], [7, 9]], depois [(1, 4), (2, 5)] e por fim fim. A soma de uma 2 por 3 com uma 2 por 2 devolve uma 2 por 2, sem mensagem, e o 3 e o 6 desaparecem. Com o zip, vale conferir antes que as dimensões são iguais, com len(a) == len(b) and len(a[0]) == len(b[0]).

O segundo erro é pedir a diagonal de uma matriz que não é quadrada, usando o número de colunas como limite:

m = [[1, 2, 3], [4, 5, 6]]
print([m[i][i] for i in range(len(m[0]))])
IndexError: list index out of range

A matriz só tem as linhas 0 e 1, mas o laço vai até a coluna 2. A diagonal só existe até o menor dos dois tamanhos, e o conceito de diagonal secundária, traço e simetria é de matriz quadrada.

O terceiro erro é o mais traiçoeiro, porque não dá mensagem. É tentar transpor uma matriz não quadrada no lugar, com a troca de m[i][j] e m[j][i]:

m = [[1, 2, 3], [4, 5, 6]]
n = len(m)
for i in range(n):
    for j in range(i + 1, n):
        m[i][j], m[j][i] = m[j][i], m[i][j]
print(m)
print("fim")

A saída é [[1, 4, 3], [2, 5, 6]] e fim. O programa rodou, trocou dois elementos, e a "transposta" saiu com 2 linhas de 3 colunas, quando devia ter 3 linhas de 2. O 3 e o 6 nem foram tocados. O remédio é a transposta em matriz nova.

O quarto erro é usar os operadores como se fossem de matriz:

a = [[1, 2], [3, 4]]
print(a * a)
TypeError: unsupported types for __mul__: 'list', 'list'

No Python de computador, a mensagem é can't multiply sequence by non-int of type 'list'. O a + 1 também falha, com unsupported types for __add__: 'list', 'int' no simulador e can only concatenate list (not "int") to list no computador. E o a + b, sem erro nenhum, só concatena. Em todos os casos a correção é a mesma: um laço ou uma compreensão.

O quinto aparece ao tentar usar o resultado do zip como se fosse uma lista:

m = [[1, 2, 3], [4, 5, 6]]
t = zip(*m)
print(len(t))
TypeError: object of type 'zip' has no len()

O zip entrega um objeto que só se percorre, e só uma vez: depois de um list(z), um segundo list(z) devolve []. A mensagem é a mesma no simulador e no Python de computador. A solução é guardar o resultado numa lista, com list(zip(*m)).

O que costuma aparecer em sala

São padrões que se repetem com quem aprende essas operações. Não são relato de uma turma específica.

Somar com o laço errado. Escrever a[i][j] + b[j][i], ou trocar a ordem dos índices em só um dos lados. Com matrizes quadradas, o resultado sai errado sem erro nenhum. Conferir um valor à mão, de uma posição fora da diagonal, descobre rápido.

Achar que a + b soma matrizes. O resultado, a lista com as linhas empilhadas, parece plausível para quem não olha o tamanho. A pista é o len: a soma de duas matrizes 2 por 3 tem 4 linhas, e devia ter 2.

Transpor com os mesmos limites. Na transposta, o laço de fora anda pelas colunas da original. Quem copia a estrutura da soma, com range(len(m)) por fora, acaba com a matriz do tamanho errado ou com um IndexError.

A troca duas vezes. A transposição no lugar com range(n) em vez de range(i + 1, n). O programa não muda a matriz, e a pessoa conclui que a troca não funciona, em vez de pensar que funcionou duas vezes.

Diagonal com dois laços. Percorrer a matriz inteira com for i e for j e testar i == j funciona, mas faz n * n passos para achar n elementos. A forma com um só laço, m[i][i], é mais simples, e entender por que ela basta é o ponto da aula.

A diagonal secundária fora por um. Escrever n - i em vez de n - 1 - i. Com i = 0, a coluna seria n, que não existe, e o erro de índice aparece logo na primeira volta, o que ajuda a perceber o "menos um".

O elemento central contado duas vezes. Ao somar as duas diagonais de uma matriz de tamanho ímpar, o centro entra duas vezes. Em alguns problemas, isso é o que se quer, e em outros precisa de um desconto.

Testar só com a matriz quadrada. Muitos erros de transposição e de soma só aparecem com uma matriz de 2 por 3. Quem testa só com 2 por 2 ou 3 por 3 não vê a diferença entre linhas e colunas.

Exercício: transposta, diagonais e simetria

Escreva um programa que leia o tamanho n de uma matriz quadrada e depois os n * n valores, e mostre a transposta, as duas diagonais, o traço e se a matriz é simétrica. O bloco usa entradas= para fornecer n = 3 e os números de 1 a 9.

n = int(input())
m = []
for i in range(n):
    linha = []
    for j in range(n):
        linha.append(int(input()))
    m.append(linha)
t = [[m[i][j] for i in range(n)] for j in range(n)]
print("transposta")
for linha in t:
    print(*linha)
print("diagonal principal", [m[i][i] for i in range(n)])
print("diagonal secundaria", [m[i][n - 1 - i] for i in range(n)])
print("traco", sum(m[i][i] for i in range(n)))
print("simetrica", m == t)
print("fim")

O simulador repete na saída os valores digitados, um por linha, e depois vêm transposta, 1 4 7, 2 5 8, 3 6 9, diagonal principal [1, 5, 9], diagonal secundaria [3, 5, 7], traco 15, simetrica False e fim.

O programa lê o n uma vez e o usa em todo lugar, no lugar de números fixos, o que o deixa certo para qualquer tamanho. A matriz é montada linha a linha, com a linha criada dentro do laço de fora. A transposta sai de uma compreensão, e a simetria é a comparação direta m == t, que compara as listas de listas elemento a elemento.

Para praticar, experimente trocar os números por uma matriz simétrica e ver o True; calcular a soma dos elementos acima da diagonal principal; somar a matriz com a sua transposta e verificar que o resultado sempre é simétrico; e trocar a leitura para uma matriz de 2 linhas por 3 colunas e ver quais linhas do programa deixam de valer.

Perguntas frequentes

Como multiplico duas matrizes? O produto de matrizes não é elemento a elemento, e sim a soma dos produtos de uma linha da primeira por uma coluna da segunda, o que pede três laços. Fica fora deste artigo. O que se viu aqui, o produto por um número, é bem mais simples. E o a * a entre listas dá erro, como mostrado.

Existe um jeito pronto de somar matrizes? Não no Python puro, nem no simulador. Em computador, bibliotecas como o NumPy fazem a + b somar de verdade, mas elas não existem no simulador. Os laços e as compreensões deste artigo resolvem as tabelas pequenas de uma placa.

O zip(*m) funciona em qualquer matriz? Em qualquer lista de listas. Se as linhas tiverem tamanhos diferentes, ele para no menor, e as sobras somem em silêncio.

A transposta é sempre uma lista de listas? Não: o zip entrega tuplas. Se for preciso alterar a transposta depois, ou compará-la com uma lista de listas, converta cada tupla com list. A comparação [(1, 4)] == [[1, 4]] dá False, porque tupla e lista são tipos diferentes.

Por que a diagonal secundária usa n - 1 - i? Porque os índices vão de 0 a n - 1. Na linha 0, a coluna é a última, n - 1. A cada linha que desce, a coluna diminui um, e n - 1 - i descreve exatamente isso.

O que é o traço? A soma da diagonal principal. Aparece em muitas fórmulas de matrizes, mas, para programar, é só um sum sobre m[i][i].

Para continuar

Os desafios Diagonal da Matriz, Soma da Matriz e Contador de Zeros praticam o acesso aos elementos e o percurso com laços aninhados, que sustentam tudo o que se viu aqui. Para rever a base, o artigo anterior, matrizes com listas de listas, traz a criação, a armadilha do asterisco e a cópia profunda, e o de operações com listas traz as compreensões. A trilha de lógica reúne os desafios em ordem.

O próximo artigo deixa as estruturas de dados e entra nos algoritmos clássicos, começando pela busca: como procurar um valor numa lista, passo a passo, e como medir quanto trabalho essa busca dá.

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