Compreensões e Geradores em Python: Técnicas Fundamentais

Compreensões de listas em Python oferecem uma sintaxe concisa para criar listas. Por exemplo, para gerar uma lista de números de 0 a 9:

lista_base = [elemento for elemento in range(10)]

Filtrar elementos é possível adicionando condições. Para obter apenas números pares:

numeros_pares = [num for num in range(10) if num % 2 == 0]

Compreensões aninhadas podem criar estruturas complexas, como pares ordenados:

pares = [(x, y) for x in range(5) for y in range(4)]

Para achatar uma lista de listas:

lista_aninhada = [[1, 2], [3, 4]]
achatar = [item for sublist in lista_aninhada for item in sublist]

Compreensões de dicionários seguem um princípio similar, gerando pares chave-valor. Exemplo com seleção aleatória:

import random

valores_originais = [0, 2, 6, 12, 84, 65, 21, 86, 26, 49]
dicionario_aleatorio = {chave: random.choice(valores_originais) for chave in range(10)}

Inverter chaves e valores em um dicionário existente:

dicionario_original = {'a': 1, 'b': 2, 'c': 3}
dicionario_invertido = {valor: chave for chave, valor in dicionario_original.items()}

Compreensões de conjuntos eliminam duplicatas automaticamente:

conjunto_numeros = {num for num in range(10)}

Geradores são objetos que produzem valores sob demanda, economizando memória. Podem ser criados com sintaxe similar às compreensões, mas com parênteses:

gerador_par = (n for n in range(50) if n % 2 == 0)
print(next(gerador_par))  # Obtém o primeiro valor
print(next(gerador_par))  # Obtém o segundo valor

Funções geradoras usam a palavra-chave yield para pausar e retomar a execução. Exemplo de uma contagem:

def contador_limite(limite):
    atual = 0
    while atual < limite:
        yield atual
        atual += 1

gen = contador_limite(5)
for valor in gen:
    print(valor)

O yield permite comunicação bidirecional com o gerador. Ao enviar valores, use send():

def gerador_interativo():
    recebido = yield "Início"
    while recebido is not None:
        recebido = yield f"Recebi: {recebido}"

gen = gerador_interativo()
print(next(gen))  # Inicializa o gerador
print(gen.send("Dados"))  # Envia um valor

Sequências como Fibonacci podem ser implementadas eficientemente com geradores:

def fibonacci(quantidade):
    a, b = 0, 1
    for _ in range(quantidade):
        yield a
        a, b = b, a + b

seq_fib = fibonacci(10)
print(list(seq_fib))

Iteradores são objetos que suportam iteração via next(). Todo gerador é um iterador, mas nem todo iterador é um gerador. Objetos iteráveis, como listas, podem ser convertidos em iteradores:

lista_iteravel = [1, 2, 3, 4]
iterador_lista = iter(lista_iteravel)
print(next(iterador_lista))  # 1
print(next(iterador_lista))  # 2

Vantagens dos iteradores incluem processamento preguiçoso e capacidade de lidar com dados sem índices. Desvantagens: não possuem comprimento definido e não permitem acesso reverso.

Decoradores em Python estendem o comportamento de funções sem modificá-las diretamente. Eles se baseiam em funções de alta ordem e closures. Uma closure ocorre quando uma função interna referencia variáveis de seu escopo externo.

def verificar_autenticacao(func):
    def wrapper(*args, **kwargs):
        print("Autenticação em andamento")
        return func(*args, **kwargs)
    return wrapper

@verificar_autenticacao
def acessar_recurso(dado):
    print(f"Acessando: {dado}")

acessar_recurso("documento_confidencial")

Decoradores podem aceitar argumentos adicoinais, exigindo uma camada extra de funções:

def decorador_com_parametro(param):
    def decorador(func):
        def wrapper(*args, **kwargs):
            if param == "ativo":
                print("Modo ativo")
            else:
                print("Modo inativo")
            return func(*args, **kwargs)
        return wrapper
    return decorador

@decorador_com_parametro("ativo")
def calcular(a, b):
    return a + b

@decorador_com_parametro("inativo")
def multiplicar(a, b):
    return a * b

print(calcular(3, 4))
print(multiplicar(3, 4))

Esta abordagem permite reutilizar lógica de autenticação, logging ou validação de maneira modular.

Tags: Python comprehensions generators iterators decorators

Publicado em 7-2 06:11