Matrizes:
uma tabela
em memória
Do conceito de linhas e colunas ao percurso linha a linha — e o primeiro algoritmo clássico de matriz: as diagonais em Python.
Do conceito de linhas e colunas ao percurso linha a linha — e o primeiro algoritmo clássico de matriz: as diagonais em Python.
Estamos no segundo capítulo de estruturas de dados. Nas duas semanas anteriores, vimos vetores: uma fila de valores. Esta semana, damos um salto de dimensão — matrizes — e na próxima fecharemos a unidade com funções.
Estrutura linear de uma dimensão. Indexação por [i], busca linear, ordenação e estatísticas.
Estrutura de duas dimensões — linhas × colunas. Indexação por [i][j], percursos e operações agregadas.
Encapsulamento de lógica reutilizável. Parâmetros, retorno, escopo. Fecha a unidade.
A1Entender por que variáveis soltas não dão conta de uma tabela 2D — e o que motiva matrizes
A1Declarar matrizes em Python e acessar elementos por (linha, coluna) sem cair em aliasing
A2Implementar o laço aninhado que percorre cada célula uma vez em ordem row-major
A2Resolver o desafio BeeCrowd 1534 — Array 123: marcar diagonais e tratar a sobreposição central
Você está estagiando em uma empresa de análise de imagens. A primeira tarefa: representar uma mini-imagem 3×4 onde cada pixel está ligado (1) ou apagado (0). Sem matriz, a ideia ingênua é 12 variáveis separadas.
p11, p12, …, p34 (12 variáveis)(3, 2)?Sem uma estrutura 2D, o código vira uma escada de ifs impossível de manter — e cresce N×M com o tamanho da imagem.
p11 = 0; p12 = 1; p13 = 0; p14 = 1
p21 = 1; p22 = 0; p23 = 1; p24 = 0
p31 = 0; p32 = 1; p33 = 1; p34 = 0
# "Ligar a linha 2 toda":
p21 = 1
p22 = 1
p23 = 1
p24 = 1
# "Contar ativos da coluna 1":
ativos_col1 = p11 + p21 + p31
# … e se a imagem virar 100×100?
Uma matriz é uma estrutura de duas dimensões: linhas × colunas. É a generalização natural do vetor — em vez de uma fila, uma grade. Cada célula é localizada por um par de índices (i, j), onde i é a linha e j a coluna.
1 é um pixel aceso. m[2][1] = 1 significa "linha 2, coluna 1, pixel aceso".
Antes de mexer com qualquer matriz, decida — e declare — qual base de indexação você usa. Confundir as duas é a fonte número um de bugs off-by-one.
Primeira linha em m[0], última em m[N-1]. É o padrão de Python — e o que usaremos no curso.
Primeira linha em m(1), última em m(N). Mais natural para humanos, mas não é o padrão da maioria das linguagens.
m[2] (base 0) ou m[3] (base 1) — e esse mal-entendido custa horas de depuração.
A memória do computador é linear — não tem "linhas" e "colunas". Quem decide a ordem é a linguagem. Em Python, C e na maioria das linguagens, vale a regra row-major: percorre a linha inteira antes de passar para a próxima.
matriz 3×4 → memória contígua na ordem (linha 0 → linha 1 → linha 2):
Existem duas formas comuns de criar uma matriz 3×4 em Python. Uma é tentadora e errada; a outra é chata e correta. A diferença muda o comportamento do programa inteiro.
# ❌ ERRADO — aliasing!
m = [[0] * 4] * 3
m[0][1] = 9
print(m)
# [[0, 9, 0, 0],
# [0, 9, 0, 0], ← também mudou
# [0, 9, 0, 0]] ← também mudou
# As 3 "linhas" são, na verdade,
# 3 referências para a MESMA lista.
# Mudar uma muda todas.
# ✅ CERTO — uma linha por vez
m = [[0] * 4 for _ in range(3)]
m[0][1] = 9
print(m)
# [[0, 9, 0, 0],
# [0, 0, 0, 0], ← intocada
# [0, 0, 0, 0]] ← intocada
# A list comprehension EXECUTA
# [0]*4 três vezes, criando
# três listas independentes.
* em listas não copia — ele repete a mesma referência. Funciona para tipos imutáveis (int, str), mas listas são mutáveis. Para criar N linhas independentes, use sempre list comprehension.
Na Aula 1 aprendemos a declarar e acessar uma matriz por (i, j). Mas qualquer programa de verdade precisa visitar todas as células: imprimir a imagem, somar valores, validar regras. Esse é o problema do percurso — e a ferramenta para resolvê-lo tem nome: laço aninhado.
Percorrer uma matriz é visitar cada elemento uma única vez. O padrão didático — e o mais comum em row-major — é linha a linha, da esquerda para a direita. Em uma matriz N × M, o percurso completo tem complexidade O(N · M).
ordem de visita em uma matriz 3×4:
for, um dentro do outroO laço externo controla a linha (i). O laço interno percorre a coluna (j). Para cada valor de i, o j varre todas as colunas — e só depois i avança.
// Pseudocódigo
para i de 0 ate n_linhas - 1 faca
para j de 0 ate n_colunas - 1 faca
processar( m[i][j] )
fim_para
fim_para
# Python — imprimir a matriz
m = [[1, 2, 3, 4],
[5, 6, 7, 8],
[9, 0, 1, 2]]
for i in range(len(m)): # linhas
for j in range(len(m[i])): # colunas
print(m[i][j], end=' ')
print() # quebra linha
i externo e j interno, percorremos linha a linha (row-major) — rápido e natural. Invertendo (j externo, i interno), percorremos coluna a coluna — funciona, mas vai contra o layout de memória do Python.
O desafio (BeeCrowd 1534): dado N, montar uma matriz N × N onde a diagonal principal vale 1, a diagonal secundária vale 2, e todos os outros valem 3. Vamos destrinchar em 5 passos antes de codar.
Leia N. O problema tem múltiplos casos até o fim da entrada — use while True + try / except EOFError.
Percorra linha a linha. for i in range(N) e inicie uma string vazia linha = "" para acumular o caractere de cada coluna.
Decida o caractere de cada coluna. for j in range(N) e use if / elif / else com as duas condições de diagonal.
Cuidado com o centro. Em N ímpar, a célula central pertence às duas diagonais — a secundária tem prioridade. Teste i + j == N - 1 ANTES de i == j.
Imprima. Após cada linha pronta, print(linha). Repita até o EOF.
if manda mais que a ordem do enunciado.
Um colega entregou esta versão. Roda, compila — mas falha em N ímpar. Olhe a saída para N = 3: a posição central deveria ser 2 e está vindo 1.
while True:
try:
N = int(input())
for i in range(N):
linha = ""
for j in range(N):
if i == j: # ⚠ principal primeiro
linha += "1"
elif i + j == N - 1: # secundária só se sobrar
linha += "2"
else:
linha += "3"
print(linha)
except EOFError:
break
Entrada: 3 Saída obtida: 1 3 2 3 1 3 ← deveria ser 2! 2 3 1 Saída esperada: 1 3 2 3 2 3 2 3 1 # Em N=3, a célula (1,1) # está nas DUAS diagonais # mas o if pega a principal # primeiro e nunca vê a 2ª.
N = 3, a célula (1, 1) satisfaz tanto i == j (principal) quanto i + j == N - 1 (secundária = 1 + 1 == 2). O if/elif avalia em ordem — quem chega primeiro vence. Trocar a ordem das duas condições resolve.
A única mudança em relação à versão bugada: a ordem das duas primeiras condições. A secundária vem antes. Agora o programa passa tanto para N par quanto ímpar.
while True:
try:
N = int(input())
for i in range(N):
linha = ""
for j in range(N):
if i + j == N - 1: # ✅ secundária PRIMEIRO
linha += "2"
elif i == j: # principal depois
linha += "1"
else:
linha += "3"
print(linha)
except EOFError:
break
Entrada:
3
4
Saída:
1 3 2
3 2 3
2 3 1
1 3 3 2
3 1 2 3
3 2 1 3
2 3 3 1
── teste com N=1, N=2,
── N=3, N=4 — todos passam
numpy. Cada linha deve ser impressa sem espaços entre os números (no enunciado original do BeeCrowd). Teste com N = 1, 2, 3, 4, 5 — preste atenção em N ímpar.
Uma matriz é uma estrutura de dados organizada em duas dimensões. Qual das alternativas abaixo a descreve corretamente?
(i, j) — daí o acesso m[i][j]. A alternativa C descreve um vetor, não uma matriz.
(i, j), acessada com m[i][j]m[0], primeira coluna em m[i][0][[0]*M]*N; use list comprehension [[0]*M for _ in range(N)]i externo (linha), j interno (coluna); percurso completo é O(N · M)Operações agregadas + Jogo da Velha — soma por linha, soma por coluna, média geral, e modelagem de jogos com matrizes. Fecharemos a semana com um Jogo da Velha completo em terminal.
BEECROWD. Problema 1534 — Array 123. BeeCrowd Online Judge, [s.d.]. Disponível em: beecrowd.com.br/judge/pt/problems/view/1534. Acesso em: 20 mai. 2026.
PYTHON SOFTWARE FOUNDATION. Data Structures — Nested List Comprehensions. The Python Tutorial, [s.d.]. Disponível em: docs.python.org/3/tutorial/datastructures.html. Acesso em: 20 mai. 2026.
FAQ Python. Why does a list multiplied by a number return repeated references? docs.python.org, [s.d.]. Disponível em: docs.python.org/3/faq/programming.html. Acesso em: 20 mai. 2026.
Base institucional: SEDUC-SP. Educação Profissional Paulista — Técnico em Desenvolvimento de Sistemas. Componente 1, Unidade 4, Semana 12 (SISANO1C1B2S12A1 e SISANO1C1B2S12A2).
Identidade visual · adaptação para apresentação HTML por Guilherme Antunes