Módulo 2 - Compreensões de lista, dicionário e conjunto

Compreensões aninhadas

11 min de leitura · por Cesar Gargiulo, revisado pela equipe ValorFinal e GuardiaSec · Atualizado em 01/07/2026

O que você vai aprender

  • Escrever uma compreensão com dois for, na ordem correta.
  • Achatar uma lista de listas em uma lista única.
  • Gerar combinações de duas sequências com uma compreensão.
  • Julgar quando o aninhamento passou do ponto e pede um for normal.

Dois for na mesma compreensão

Uma compreensão pode ter mais de um for, e isso corresponde a um laço dentro do outro. A pegadinha é a ordem: ela é a mesma que você escreveria nos laços normais, de fora para dentro. O primeiro for é o externo, o segundo é o interno. Muita gente inverte na cabeça porque em compreensões acha que se lê de trás para frente, mas não: a ordem dos for é a ordem natural dos laços.

# Laco aninhado tradicional:
pares = []
for letra in "AB":
    for numero in [1, 2, 3]:
        pares.append(f"{letra}{numero}")

print(pares)  # ['A1', 'A2', 'A3', 'B1', 'B2', 'B3']

O laço aninhado clássico: para cada letra, percorre todos os números.

# A mesma coisa como compreensao, os for na MESMA ordem:
pares = [f"{letra}{numero}" for letra in "AB" for numero in [1, 2, 3]]

print(pares)  # ['A1', 'A2', 'A3', 'B1', 'B2', 'B3']

for letra vem primeiro (laço de fora) e for numero depois (laço de dentro).

Achatar uma lista de listas

Um dos usos mais úteis do aninhamento é achatar uma lista de listas, transformando algo com dois níveis em uma sequência plana. Imagine uma matriz, que em Python costuma ser uma lista de linhas, cada linha sendo uma lista de números. Para juntar todos os números em uma lista só, você percorre cada linha e, dentro dela, cada item. Em compreensão, isso vira uma linha, com o for de fora pegando as linhas e o de dentro pegando os itens.

matriz = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]

plana = [item for linha in matriz for item in linha]

print(plana)  # [1, 2, 3, 4, 5, 6, 7, 8, 9]

Achatar: for linha in matriz (de fora) e for item in linha (de dentro).

Há também o caso oposto e igualmente comum: montar uma matriz com uma compreensão dentro de outra. Aqui os colchetes aparecem duas vezes, os de fora criando a lista de linhas e os de dentro criando cada linha. Este é o ponto em que muita gente decide, com razão, que um for tradicional lê melhor. A versão em compreensão é elegante, mas exige leitura atenta, então use com bom senso.

# Tabuada 1 a 3, cada linha e uma lista:
tabuada = [[linha * col for col in range(1, 4)] for linha in range(1, 4)]

for linha in tabuada:
    print(linha)
# [1, 2, 3]
# [2, 4, 6]
# [3, 6, 9]

Compreensão dentro de compreensão cria uma matriz. Bonito, mas pede atenção ao ler.

Até onde o aninhamento vale a pena

Compreensão aninhada é o ponto do módulo em que o poder e o risco se cruzam. Com dois for ou uma compreensão dentro da outra, você economiza linhas, mas cada nível a mais cobra um preço de leitura. A pergunta a fazer nunca muda: quem ler isto daqui a três meses vai entender rápido? Se a resposta for não, os laços separados, com nomes claros e indentação, são a escolha profissional. Escrever menos não é o objetivo; escrever claro é.

Vale guardar que quase toda compreensão aninhada tem uma versão em laços comuns que faz exatamente a mesma coisa. Elas não competem; a compreensão é um atalho para os casos claros, e o for tradicional é o porto seguro para os casos densos. Um bom programador intermediário sabe escrever as duas e escolhe a que deixa a intenção mais óbvia naquele contexto. Essa escolha consciente é mais valiosa que decorar a sintaxe.

Teste rápido

Qual compreensão achata [[1, 2], [3, 4]] em [1, 2, 3, 4]?

Perguntas frequentes

Por que a ordem dos dois for me confunde?
Porque a expressão fica na frente, e o cérebro tende a achar que o resto vem ao contrário. Não vem. Os for aparecem na mesma ordem dos laços aninhados: o primeiro for é o externo, o segundo é o interno. Uma dica é escrever mentalmente os laços normais primeiro e depois só colar os for na mesma sequência.
Qual a diferença entre achatar e criar uma matriz?
Achatar usa dois for e um só nível de colchetes: junta tudo em uma lista plana. Criar matriz usa colchetes dentro de colchetes: a compreensão de dentro monta cada linha e a de fora junta as linhas. O número de níveis de colchetes é a pista de qual das duas você está fazendo.
Compreensão aninhada é sempre má ideia?
Não. Achatar uma lista de listas ou aplicar um filtro extra costuma ficar claro. O problema é o excesso: três for, condições pesadas e vários níveis de colchetes viram um enigma. A regra é ler a linha e perguntar se a intenção salta aos olhos. Se não, quebre em laços normais.
Existe uma função pronta para achatar listas?
A biblioteca padrão tem itertools.chain.from_iterable, que achata de forma eficiente e é ótima para listas grandes. Você conhece o itertools no módulo da biblioteca padrão. Para casos simples e didáticos, a compreensão com dois for resolve bem e deixa a mecânica visível.
Posso misturar filtro com aninhamento?
Pode, o if vai no fim como sempre, por exemplo [item for linha in matriz for item in linha if item > 0]. Funciona, mas some rápido em legibilidade. Sempre que a linha começar a exigir releitura, considere separar em laços com nomes explícitos.
A matriz precisa ter linhas do mesmo tamanho?
Para achatar, não. A compreensão percorre cada linha até o fim, então linhas de tamanhos diferentes funcionam e todos os itens entram na lista plana. Já operações que assumem uma grade retangular, como transpor, é que exigem linhas iguais, mas isso é outro assunto.

Fontes

Seu progresso fica salvo neste aparelho. Assinantes sincronizam entre os aparelhos.