As compreensões de lista (list comprehensions) são um dos recursos mais elegantes e poderosos da linguagem Python. Elas permitem criar novas listas de forma concisa, aplicando transformações e filtros em uma única linha de código, substituindo loops tradicionais e funções como map() e filter() na maioria dos casos.
Se você está começando no mundo Python, dominar as compreensões de lista vai elevar significativamente a qualidade e legibilidade do seu código. Neste guia completo, você vai aprender desde a sintaxe básica até técnicas avançadas, com exemplos práticos que pode aplicar imediatamente.
O que são Compreensões de Lista?
Uma compreensão de lista é uma construção sintática que permite criar uma nova lista iterando sobre uma sequência existente (ou qualquer iterável) e opcionalmente aplicando uma condição de filtro. A sintaxe básica é:
[nova_expressao for item in iteravel if condicao]
A expressão nova_expressao é calculada para cada item que satisfaz a condicao (se houver), e o resultado é adicionado à nova lista.
Sintaxe Básica
Vamos começar com o exemplo mais simples: criar uma lista com os quadrados dos números de 0 a 9.
Usando um loop for tradicional:
quadrados = []
for numero in range(10):
quadrados.append(numero ** 2)
print(quadrados) # [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
Com compreensão de lista:
quadrados = [numero ** 2 for numero in range(10)]
print(quadrados) # [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
A diferença é notável: em uma única linha, eliminamos a necessidade de inicializar a lista vazia, escrever o loop e chamar append(). O código fica mais limpo, mais legível e, na maioria dos casos, mais rápido.
De acordo com a documentação oficial do Python, as compreensões de lista consistem em colchetes contendo uma expressão seguida por uma cláusula for e zero ou mais cláusulas for ou if.
Por que Usar Compreensões de Lista?
As compreensões de lista oferecem três vantagens principais em relação aos loops tradicionais:
- Concisão: reduzem várias linhas de código a uma única expressão
- Legibilidade: uma vez que você aprende a sintaxe, o código expressa claramente a intenção
- Performance: geralmente são mais rápidas que loops
forequivalentes
Vamos analisar a diferença de performance com um exemplo prático. Criar uma lista com os números pares de 0 a 999999:
import time
inicio = time.time()
pares_loop = []
for i in range(1000000):
if i % 2 == 0:
pares_loop.append(i)
fim_loop = time.time()
inicio = time.time()
pares_comp = [i for i in range(1000000) if i % 2 == 0]
fim_comp = time.time()
print(f"Loop for: {fim_loop - inicio:.4f}s")
print(f"Compreensão: {fim_comp - inicio:.4f}s")
Na prática, as compreensões de lista são significativamente mais rápidas porque a operação é executada em C por baixo dos panos, sem a necessidade de chamar o método append() a cada iteração. Este ganho de performance é especialmente relevante quando você está processando grandes volumes de dados.
O PEP 202, que introduziu as compreensões de lista no Python 2.0, explica a motivação por trás desse recurso: fornecer uma maneira mais sucinta e legível de criar listas baseadas em sequências existentes.
Exemplos Práticos do Dia a Dia
1. Transformação de Strings
Converter uma lista de strings para maiúsculas:
nomes = ['ana', 'joão', 'maria', 'pedro']
nomes_maiusculos = [nome.upper() for nome in nomes]
print(nomes_maiusculos) # ['ANA', 'JOÃO', 'MARIA', 'PEDRO']
2. Filtragem com Condicional
Selecionar apenas os números pares:
numeros = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
pares = [num for num in numeros if num % 2 == 0]
print(pares) # [2, 4, 6, 8, 10]
3. Transformação com Condicional (if-else)
Diferente do if filtrante, você pode usar if-else antes do for para transformar condicionalmente:
numeros = [1, 2, 3, 4, 5]
rotulos = ['par' if num % 2 == 0 else 'ímpar' for num in numeros]
print(rotulos) # ['ímpar', 'par', 'ímpar', 'par', 'ímpar']
4. Achatamento de Matrizes
Transformar uma matriz 2D em uma lista 1D:
matriz = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
plano = [num for linha in matriz for num in linha]
print(plano) # [1, 2, 3, 4, 5, 6, 7, 8, 9]
5. Aplicar Função a Elementos
def celsius_para_fahrenheit(c):
return (c * 9/5) + 32
temperaturas_c = [0, 10, 20, 30, 40]
temperaturas_f = [celsius_para_fahrenheit(c) for c in temperaturas_c]
print(temperaturas_f) # [32.0, 50.0, 68.0, 86.0, 104.0]
6. Extrair Dados de Dicionários
alunos = [
{'nome': 'Ana', 'nota': 8.5},
{'nome': 'João', 'nota': 6.0},
{'nome': 'Maria', 'nota': 9.2},
{'nome': 'Pedro', 'nota': 4.5}
]
aprovados = [aluno['nome'] for aluno in alunos if aluno['nota'] >= 7.0]
print(aprovados) # ['Ana', 'Maria']
Compreensões de Lista Aninhadas
Compreensões aninhadas são úteis para trabalhar com estruturas de dados multidimensionais. Vamos criar uma matriz identidade 4x4:
n = 4
identidade = [[1 if i == j else 0 for j in range(n)] for i in range(n)]
for linha in identidade:
print(linha)
# [1, 0, 0, 0]
# [0, 1, 0, 0]
# [0, 0, 1, 0]
# [0, 0, 0, 1]
Outro exemplo clássico: transpor uma matriz:
matriz = [[1, 2, 3], [4, 5, 6]]
transposta = [[linha[i] for linha in matriz] for i in range(3)]
print(transposta) # [[1, 4], [2, 5], [3, 6]]
Compreensões com Múltiplas Condições
Você pode encadear múltiplas condições if:
numeros = range(1, 51)
filtrados = [n for n in numeros if n % 2 == 0 if n % 5 == 0]
print(filtrados) # [10, 20, 30, 40, 50]
# Equivalente a: if n % 2 == 0 and n % 5 == 0
Compreensões de Lista vs map() e filter()
Python oferece as funções map() e filter() da programação funcional, que podem fazer coisas similares:
numeros = [1, 2, 3, 4, 5]
# Usando map()
quadrados_map = list(map(lambda x: x ** 2, numeros))
# Usando compreensão
quadrados_comp = [x ** 2 for x in numeros]
# Usando filter()
pares_filter = list(filter(lambda x: x % 2 == 0, numeros))
# Usando compreensão
pares_comp = [x for x in numeros if x % 2 == 0]
A comunidade Python e o próprio Guido van Rossum recomendam o uso de compreensões de lista em vez de map() e filter() com lambda, pois o código fica mais legível.
O tutorial da Real Python sobre list comprehensions aprofunda ainda mais essa comparação e mostra benchmarks detalhados.
Boas Práticas
1. Mantenha a Simplicidade
Se a compreensão de lista ficar muito longa ou complexa, prefira usar um loop tradicional. Uma boa regra é: se a compreensão ultrapassar 80 caracteres, considere quebrá-la em múltiplas linhas ou usar um loop.
# Ruim (muito longa)
resultado = [funcao_complicada(x, y) for x in lista_x for y in lista_y if condicao_1(x) and condicao_2(y) and validacao(x, y)]
# Melhor (loop explícito)
resultado = []
for x in lista_x:
for y in lista_y:
if condicao_1(x) and condicao_2(y) and validacao(x, y):
resultado.append(funcao_complicada(x, y))
2. Use Generators para Grandes Volumes
Se você está processando uma quantidade muito grande de dados e não precisa armazenar todos os resultados na memória, use uma expressão geradora (com parênteses em vez de colchetes):
# Compreensão de lista (tudo na memória)
quadrados_lista = [x ** 2 for x in range(10_000_000)]
# Expressão geradora (lazy evaluation)
quadrados_gen = (x ** 2 for x in range(10_000_000))
# Itera sob demanda
for valor in quadrados_gen:
if valor > 100:
break
O site GeeksforGeeks tem uma excelente seção comparando generators e list comprehensions com exemplos práticos.
3. Evite Efeitos Colaterais
Compreensões de lista devem ser usadas para criar novas listas, não por seus efeitos colaterais. Evite:
# Ruim (efeito colateral)
[print(item) for item in lista]
# Bom
for item in lista:
print(item)
4. Prefira Compreensões a map()/filter() com lambda
A menos que você já tenha uma função definida, compreensões são mais legíveis:
# Compreensão (legível)
resultados = [len(palavra) for palavra in palavras]
# map com lambda (menos legível)
resultados = list(map(lambda p: len(p), palavras))
# map com função existente (ok)
resultados = list(map(len, palavras))
Casos de Uso Avançados
List Comprehensions com zip()
Combinar listas paralelas:
nomes = ['Ana', 'João', 'Maria']
idades = [25, 32, 28]
pessoas = [f'{nome} tem {idade} anos' for nome, idade in zip(nomes, idades)]
print(pessoas) # ['Ana tem 25 anos', 'João tem 32 anos', 'Maria tem 28 anos']
Compreensões com else (Operador Ternário)
valores = [10, -5, 0, 8, -3, 15]
classificados = ['positivo' if v > 0 else 'negativo' if v < 0 else 'zero' for v in valores]
print(classificados) # ['positivo', 'negativo', 'zero', 'positivo', 'negativo', 'positivo']
Compreensões com enumerate()
palavras = ['python', 'seo', 'artigo', 'código']
com_indices = [(i, palavra.upper()) for i, palavra in enumerate(palavras)]
print(com_indices) # [(0, 'PYTHON'), (1, 'SEO'), (2, 'ARTIGO'), (3, 'CÓDIGO')]
Quando NÃO Usar Compreensões de Lista
Apesar de poderosas, existem situações em que compreensões de lista não são a melhor escolha:
- Lógica muito complexa: loops com múltiplos condicionais aninhados e transformações extensas
- Depuração: é mais fácil adicionar
print()ou usar um debugger em loops tradicionais - Grandes volumes com memória limitada: use expressões geradoras
- Quando você precisa interromper o loop antecipadamente (
break) - Quando você precisa modificar a lista original no lugar
O tutorial da W3Schools tem uma introdução amigável que aborda os fundamentos para iniciantes.
Comparação com Outras Linguagens
Se você vem de outras linguagens, aqui está uma comparação rápida:
JavaScript (Array.map + filter):
let numeros = [1, 2, 3, 4, 5];
let paresQuadrados = numeros.filter(n => n % 2 === 0).map(n => n ** 2);
// [4, 16]
Python (list comprehension):
numeros = [1, 2, 3, 4, 5]
pares_quadrados = [n ** 2 for n in numeros if n % 2 == 0]
# [4, 16]
A sintaxe do Python é geralmente considerada mais limpa para essa operação específica.
Conclusão
As compreensões de lista são um dos recursos mais distintivos e úteis do Python. Elas permitem escrever código mais limpo, mais rápido e mais expressivo. Dominar esse recurso é essencial para qualquer programador Python, seja você um iniciante ou um profissional experiente.
Lembre-se das principais lições:
- Use compreensões para substituir loops simples de transformação e filtro
- Mantenha suas compreensões legíveis e concisas
- Prefira expressões geradoras para grandes conjuntos de dados
- Evite efeitos colaterais dentro de compreensões
- Conheça os limites: nem tudo deve ser uma compreensão de lista
O Programiz oferece mais exemplos interativos para você praticar e consolidar o conhecimento.
Agora que você entende o poder das compreensões de lista, pratique com seus próprios dados. Tente refatorar loops antigos dos seus projetos para usar compreensões — você vai se surpreender com a diferença na qualidade do código. Continue estudando e explorando o ecossistema Python para descobrir ainda mais recursos que tornam essa linguagem tão especial.