Funções Essenciais do Python para Automação


Este artigo explora algumas funções essenciais do Python — enumerate(), reversed(), zip(), map(), filter(), sorted() e lambda — mostrando como elas podem melhorar scripts, simplificar o processamento de dados e otimizar a gestão de redes. Este é um guia rápido e prático que utilizo sempre que preciso revisar algumas habilidades em Python.
Vamos começar!
enumerate()
Ao trabalhar com iteradores, muitas vezes é necessário acompanhar o número de iterações. O Python simplifica essa tarefa com a função integrada enumerate(). Ela adiciona um contador a um iterável e retorna um objeto enumerador, que pode ser usado diretamente em loops ou convertido em uma lista de tuplas com a função list().
Exemplo:
import requests
# Lista de dispositivos de rede
dispositivos_rede = [
'10.0.0.1',
'10.0.0.2',
'10.0.0.3',
]
# Função para testar a conectividade de um dispositivo
def ping_dispositivo(ip_dispositivo):
try:
resposta = requests.get(f'http://{ip_dispositivo}', timeout=1)
return resposta.status_code == 200
except requests.RequestException:
return False
# Usando enumerate para iterar pela lista de dispositivos
for indice, ip_dispositivo in enumerate(dispositivos_rede, start=1):
acessivel = ping_dispositivo(ip_dispositivo)
status = "acessível" if acessivel else "inacessível"
print(f"Dispositivo {indice}: {ip_dispositivo} está {status}")
### RESULTADO
# Dispositivo 1: 10.0.0.1 está acessível
# Dispositivo 2: 10.0.0.2 está inacessível
# Dispositivo 3: 10.0.0.3 está inacessível
obj = enumerate(dispositivos_rede, start=1)
print(list(obj))
## RESULTADO
# [(1, '10.0.0.1'), (2, '10.0.0.2'), (3, '10.0.0.3')]
Nota: O parâmetro start=1 faz o contador começar em 1 em vez de 0.
reversed()
Para inverter a ordem de um iterador:
dispositivos_rede = [
'10.0.0.1',
'10.0.0.2',
'10.0.0.3',
]
for ip in reversed(dispositivos_rede):
print(ip)
## SAÍDA
# 10.0.0.3
# 10.0.0.2
# 10.0.0.1
Melhoria: Adicionei dois pontos (:) que faltavam no original para corrigir a sintaxe do for.
zip()
A função zip() retorna um iterador de tuplas, onde cada tupla contém elementos dos iteradores de entrada emparelhados pelo índice. A primeira tupla contém os primeiros elementos de cada iterador, a segunda contém os segundos, e assim por diante. Se os iteradores tiverem tamanhos diferentes, o resultado para no menor iterador, descartando elementos excedentes dos maiores.
Exemplo:
# Exemplo usando a função zip em Python
# Duas listas para combinar
lista1 = ['a', 'b', 'c', 'd']
lista2 = [1, 2, 3, 4]
# Usando zip para combinar as listas
lista_combinada = zip(lista1, lista2)
# Convertendo o objeto combinado em lista e exibindo
print(list(lista_combinada))
"""
SAÍDA:
[('a', 1), ('b', 2), ('c', 3), ('d', 4)]
"""
# Se as listas têm tamanhos diferentes, zip para no menor
lista3 = [1, 2, 3]
lista_combinada_curta = zip(lista1, lista3)
print(list(lista_combinada_curta))
"""
SAÍDA:
[('a', 1), ('b', 2), ('c', 3)]
"""
# Desfazendo o zip
deszip1, deszip2 = zip(*zip(lista1, lista2))
print("Lista1 deszipada:", deszip1)
print("Lista2 deszipada:", deszip2)
# SAÍDA: ('a', 'b', 'c', 'd') e (1, 2, 3, 4)
map(), filter(), sorted() e lambda
As funções map(), filter() e sorted() são fundamentais para programação funcional em Python, permitindo processar dados de forma concisa e eficiente. Compreendê-las melhora sua capacidade de automatizar tarefas de engenharia de redes.
lambda
Uma função lambda é uma função anônima definida com a palavra-chave lambda, em vez de def, usada para operações simples em uma única linha. Elas são frequentemente passadas como argumentos para funções como map(), filter() ou sorted().
Sintaxe: lambda argumentos: expressão
Diferente de funções normais, lambdas contêm apenas uma expressão e retornam seu resultado implicitamente.
Exemplo:
# Função lambda simples
x = lambda a: a * a
print(x(2)) # SAÍDA: 4
# Convertendo para endereço IP
import ipaddress
x = lambda ip: ipaddress.ip_address(ip)
print(x('192.168.0.1')) # SAÍDA: IPv4Address('192.168.0.1')
print(x(3232235521)) # SAÍDA: IPv4Address('192.168.0.1')
map()
A função map() aplica uma função especificada a cada item de um iterável (como lista ou tupla) e retorna um objeto mapa (um iterador) com os resultados.
Sintaxe: map(função, iterável, …)
Exemplo:
dispositivos = ['roteador1', 'switch1', 'firewall1', 'roteador2']
# Convertendo para maiúsculas
dispositivos = map(lambda d: d.upper(), dispositivos)
print(list(dispositivos))
## SAÍDA: ['ROTEADOR1', 'SWITCH1', 'FIREWALL1', 'ROTEADOR2']
filter()
A função filter() cria um iterador com elementos de um iterável que satisfazem uma condição específica, definida por uma função que retorna True ou False.
Sintaxe: filter(função, iterável)
Exemplo:
# Filtrando dispositivos ativos
dispositivos = [
{'nome': 'Roteador1', 'status': 'ativo', 'ip': '192.168.1.1'},
{'nome': 'Switch1', 'status': 'inativo', 'ip': '192.168.1.2'},
{'nome': 'Firewall1', 'status': 'ativo', 'ip': '192.168.1.3'},
{'nome': 'Roteador2', 'status': 'inativo', 'ip': '192.168.1.4'},
]
ativos = list(filter(lambda dev: dev['status'] == 'ativo', dispositivos))
print(ativos)
"""
SAÍDA:
[{'nome': 'Roteador1', 'status': 'ativo', 'ip': '192.168.1.1'},
{'nome': 'Firewall1', 'status': 'ativo', 'ip': '192.168.1.3'}]
"""
sorted()
A função sorted() retorna uma nova lista ordenada a partir dos itens de um iterável, sem alterar o original.
Sintaxe: sorted(iterável, *, key=None, reverse=False)
Exemplo:
# Ordenando interfaces por utilização de banda
interfaces = [
{'nome': 'Gig0/1', 'utilização': 75},
{'nome': 'Gig0/2', 'utilização': 50},
{'nome': 'Gig0/3', 'utilização': 90},
{'nome': 'Gig0/4', 'utilização': 20},
]
ordenadas = sorted(interfaces, key=lambda iface: iface['utilização'], reverse=False)
print(ordenadas)
"""
SAÍDA:
[{'nome': 'Gig0/4', 'utilização': 20},
{'nome': 'Gig0/2', 'utilização': 50},
{'nome': 'Gig0/1', 'utilização': 75},
{'nome': 'Gig0/3', 'utilização': 90}]
"""
Resumo das Funções
Função | Propósito | Retorna |
map() | Aplica uma função a cada item de um iterável | Um objeto mapa (iterador) |
filter() | Filtra itens com base em uma condição | Um objeto filtro (iterador) |
sorted() | Ordena os itens de um iterável | Uma nova lista ordenada |
Boas Práticas
Use lambda para Simplicidade:
Para lógicas simples e de uso único, funções lambda tornam o código mais conciso.Combine com List Comprehensions:
Embora map() e filter() sejam úteis, list comprehensions podem ser mais legíveis e idiomáticas em Python.Priorize Legibilidade:
Se uma expressão com map() ou filter() ficar complexa, prefira um loop for ou uma função nomeada.
Aplicações em Automação de Redes
Essas funções são valiosas na automação de redes para processar dados de dispositivos, configurações e logs:
Configurações de Dispositivos:
map(): Aplicar mudanças em uma lista de dispositivos.
filter(): Selecionar dispositivos que precisam de atualizações.
sorted(): Ordenar dispositivos por prioridade ou localização.
Análise de Logs:
map(): Extrair campos específicos de logs brutos.
filter(): Identificar logs com erros ou violações de segurança.
sorted(): Organizar logs por ordem cronológica ou gravidade.
Gestão de Inventário:
map(): Gerar relatórios de inventário.
filter(): Identificar dispositivos inativos ou em manutenção.
sorted(): Ordenar dispositivos por função ou localização.
Dicionários
Dicionários são estruturas poderosas em Python para armazenar pares chave-valor, ideais para gerenciar configurações e dados de rede. Dominar sua manipulação melhora a eficiência na automação.
Mesclando Dicionários
# Mesclando dicionários
config1 = {'nome': 'roteador1', 'ip': '192.168.1.1'}
config2 = {'usuário': 'admin', 'senha': 'admin123'}
config_mesclada = {**config1, **config2}
print(config_mesclada)
"""
SAÍDA:
{'nome': 'roteador1',
'ip': '192.168.1.1',
'usuário': 'admin',
'senha': 'admin123'}
"""
Simplificando com defaultdict
O módulo collections oferece defaultdict, que fornece valores padrão para chaves inexistentes.
from collections import defaultdict
status_interfaces = defaultdict(lambda: 'desativada')
status_interfaces['Gig0/1'] = 'ativa'
print(status_interfaces['Gig0/1']) # SAÍDA: ativa
print(status_interfaces['Gig0/2']) # SAÍDA: desativada (padrão)
Filtrando com Comprehensions
interfaces = {'Gig0/1': 'ativa', 'Gig0/2': 'desativada', 'Gig0/3': 'ativa'}
ativas = {iface: status for iface, status in interfaces.items() if status == 'ativa'}
print(ativas)
# SAÍDA: {'Gig0/1': 'ativa', 'Gig0/3': 'ativa'}
Acessando Informações
info_dispositivo = {'nome': 'roteador1', 'fabricante': 'cisco'}
# Acesso obrigatório (erro se a chave não existe)
# tipo = info_dispositivo['tipo'] # KeyError: 'tipo'
# Usando get() com valor padrão
tipo = info_dispositivo.get('tipo', 'desconhecido')
print(tipo) # SAÍDA: desconhecido
Invertendo Dicionários
mapeamento_vlan = {10: 'Vendas', 20: 'Engenharia', 30: 'RH'}
nome_para_vlan = {v: k for k, v in mapeamento_vlan.items()}
print(nome_para_vlan)
# SAÍDA: {'Vendas': 10, 'Engenharia': 20, 'RH': 30}
Atualizando Dicionários
config1 = {'nome': 'roteador1', 'ip': '192.168.1.1'}
config2 = {'ip': '192.168.1.2', 'local': 'Centro de Dados'}
config1.update(config2)
print(config1)
# SAÍDA: {'nome': 'roteador1', 'ip': '192.168.1.2', 'local': 'Centro de Dados'}
Removendo Itens
info_dispositivo = {'nome': 'roteador1', 'fabricante': 'cisco', 'ip': '192.168.1.1'}
fabricante = info_dispositivo.pop('fabricante')
print(fabricante) # SAÍDA: cisco
print(info_dispositivo) # SAÍDA: {'nome': 'roteador1', 'ip': '192.168.1.1'}
Usando setdefault()
dispositivo = {'Roteador1': 0}
dispositivo.setdefault('Roteador2', 0)
dispositivo.setdefault('Roteador1', 10) # Não altera, pois já existe
print(dispositivo) # SAÍDA: {'Roteador1': 0, 'Roteador2': 0}
Correção: O original tinha device_stats no print, mas a variável era device. Ajustei para consistência.
Resumo de Funções e Técnicas de Dicionários
Função/Técnica | Propósito | Retorno |
{**dict1, **dict2} | Mescla dicionários | Novo dicionário mesclado |
defaultdict | Fornece valores padrão para chaves ausentes | Dicionário com valores padrão |
Comprehensions | Filtra e transforma dicionários | Novo dicionário filtrado |
.update() | Atualiza com pares chave-valor | Modifica o dicionário original |
.pop() | Remove uma chave e retorna seu valor | Valor removido |
.setdefault() | Define valor padrão se a chave não existe | Valor da chave após definição |
Conclusão
Ao dominar enumerate(), reversed(), zip(), map(), filter(), sorted() e operações com dicionários, você pode criar scripts de automação de redes mais eficientes e legíveis. Essas ferramentas ajudam a reduzir esforços manuais e erros em infraestruturas complexas.
Equilibre o uso de programação funcional com a clareza do código. Em tarefas complexas, loops tradicionais ou funções nomeadas podem ser mais fáceis de entender e manter.
Subscribe to my newsletter
Read articles from pDamasceno directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by
