Generators em Python: Iteração Eficiente e Casos de Uso Avançados
Generators em Python
Descubra como generators Python simplificam iteração, reduzem boilerplate e melhoram uso de memória comparado a iteradores tradicionais.
O Que São Generators?
Construir iterador customizado em Python geralmente requer classe que implemente __iter__() e __next__(), gerencie estado interno e levante StopIteration quando terminado. Generators eliminam esse boilerplate permitindo escrever função simples que produz valores um por vez.
Em resumo, generator é função que retorna iterador. Corpo da função executa preguiçosamente, pausando após cada yield e retomando em chamadas subsequentes.
Criar Generators em Python
Definir generator é tão simples quanto escrever função normal e substituir return por yield:
def my_gen():
n = 1
print('This is printed first')
yield n
n += 1
print('This is printed second')
yield n
n += 1
print('This is printed at last')
yield n
Chamar my_gen() retorna iterador que começa executando apenas quando next() chamado.
a = my_gen()
next(a) # imprime primeira mensagem e retorna 1
next(a) # imprime segunda mensagem e retorna 2
next(a) # imprime última mensagem e retorna 3
next(a) # levanta StopIteration
Variáveis locais persistem entre yields, mas generator pode ser iterado apenas uma vez. Para recomeçar, crie nova instância.
Como generator é iterador, você pode loop sobre ele diretamente:
for item in my_gen():
print(item)
Padrões Comuns de Generators
Invertendo String
def rev_str(s):
for i in range(len(s)-1, -1, -1):
yield s[i]
for char in rev_str('hello'):
print(char)
Funciona com qualquer iterável (lista, tupla, etc.).
Generator Expressions
Generators anônimos podem ser criados com parênteses, similar a list comprehensions:
my_list = [1, 3, 6, 10]
# List comprehension
squares_list = [x**2 for x in my_list]
# Generator expression
squares_gen = (x**2 for x in my_list)
print(squares_list)
print(squares_gen)
Generator produz valores sob demanda:
a = (x**2 for x in my_list)
print(next(a)) # 1
print(next(a)) # 9
print(next(a)) # 36
print(next(a)) # 100
next(a) # StopIteration
Generator expressions podem ser passadas diretamente para funções como sum ou max sem parênteses circundantes.
Por Que Usar Generators?
- Implementação Concisa: Substitui classes de iterador verbosas com poucas linhas de código.
- Eficiência de Memória: Produz um item por vez, ideal para sequências grandes ou infinitas.
- Streams Infinitos: Representam fontes de dados infinitas (ex.:
while True: yield). - Composição de Pipeline: Encadeie múltiplos generators para processamento de dados limpo e legível.
Exemplo: Potência de Dois
def pow_two_gen(max_n=0):
n = 0
while n < max_n:
yield 2 ** n
n += 1
Exemplo: Somando Quadrados de Números Fibonacci
def fibonacci_numbers(count):
a, b = 0, 1
for _ in range(count):
a, b = b, a + b
yield a
def square(nums):
for n in nums:
yield n ** 2
print(sum(square(fibonacci_numbers(10)))) # 4895
Generators permitem código elegante, eficiente e manutenível para ampla gama de cenários de iteração.
python
- Dominando Operadores em Python: Guia Completo
- Dominando Argumentos de Funções em Python: Parâmetros Posicionais, Nomeados e Padrão
- Dominando Dicionários em Python: Criação, Manipulação e Técnicas Avançadas
- Generators em Python: Iteração Eficiente e Casos de Uso Avançados
- Closures em Python Explicados: Como Funções Aninhadas Capturam Variáveis
- Dominando Decorators em Python: Aprimore Funções com Técnicas de Especialista
- Dominando Funções Lambda em Python: Exemplos Práticos e Boas Práticas
- Função abs() em Python: Calcular Valores Absolutos para Números e Complexos
- Função round() em Python Explicada com Exemplos Práticos
- Dominando a Função map() do Python: Sintaxe, Exemplos e Boas Práticas