def nome_da_funcao(parametros):
<instruções>
...
return <valor> # opcional5 Funções
Até aqui, nossos programas seguiam um fluxo linear: o Python executava cada instrução na ordem em que ela aparecia. Essa abordagem funciona bem para tarefas simples, mas rapidamente se torna problemática à medida que os programas crescem.
Imagine que você precisa calcular o PIB pela ótica da despesa em vinte cenários diferentes. Sem funções, você repetiria a mesma fórmula vinte vezes — e bastaria um erro em uma das cópias para comprometer toda a análise. Funções resolvem esse problema: elas permitem que um bloco de código seja escrito uma única vez e reutilizado quantas vezes for necessário, com diferentes valores de entrada.
💡 Analogia econômica: pense em uma função como uma máquina de produção. Você fornece insumos (parâmetros), a máquina executa um processo (instruções) e entrega um produto (retorno). A mesma máquina pode ser acionada várias vezes com insumos diferentes, sempre produzindo o resultado correto.
5.1 Definindo uma função
Para definir uma função em Python, usamos a palavra-chave def, seguida do nome da função e dos parâmetros entre parênteses. Todo o bloco de código indentado abaixo do cabeçalho fará parte da função.
Os elementos da sintaxe são:
def: indica ao Python que uma função está sendo definida.nome_da_funcao: nome descritivo que indica o que a função faz.parametros: valores que a função recebe para processar (opcional).return: devolve um resultado para quem chamou a função (opcional).
O exemplo mais simples é uma função sem parâmetros:
def saudacao():
print("Olá, seja bem-vindo(a)!")
saudacao()Olá, seja bem-vindo(a)!
5.2 Parâmetros
Os parâmetros tornam as funções flexíveis: permitem que diferentes valores sejam processados sem alterar o código da função. O mesmo bloco pode ser reutilizado em várias partes do programa com diferentes entradas.
def saudacao(nome):
print(f"Olá, {nome}! Seja bem-vindo(a)!")
saudacao("Arthur")
saudacao("Mariana")Olá, Arthur! Seja bem-vindo(a)!
Olá, Mariana! Seja bem-vindo(a)!
5.2.1 Valores padrão
Podemos atribuir um valor padrão a um parâmetro. Se nenhum argumento for passado, o Python usa o padrão automaticamente:
def saudacao(nome="visitante"):
print(f"Olá, {nome}! Seja bem-vindo(a)!")
saudacao("Arthur")
saudacao() # usa o padrão: "visitante"Olá, Arthur! Seja bem-vindo(a)!
Olá, visitante! Seja bem-vindo(a)!
5.2.2 Parâmetros posicionais e nomeados
Quando uma função recebe vários parâmetros, o Python os associa pela ordem em que são passados — isso é chamado de argumento posicional:
def apresentar(nome, curso):
print(f"Meu nome é {nome} e o meu curso é {curso}")
apresentar("Arthur", "Economia")Meu nome é Arthur e o meu curso é Economia
Se a ordem for trocada acidentalmente, o resultado fica semanticamente incorreto:
apresentar("Economia", "Arthur") # saída incorreta!Meu nome é Economia e o meu curso é Arthur
Para evitar esse tipo de erro, podemos usar argumentos nomeados, informando explicitamente a qual parâmetro cada valor pertence. Com argumentos nomeados, a ordem não importa:
apresentar(nome="Arthur", curso="Economia")
apresentar(curso="Economia", nome="Arthur") # mesmo resultadoMeu nome é Arthur e o meu curso é Economia
Meu nome é Arthur e o meu curso é Economia
5.2.3 Exemplo: juros compostos
A fórmula de juros compostos \(M = C \cdot (1 + i)^t\) é um conceito central em finanças. O parâmetro padrão periodos=1 é útil quando queremos calcular o rendimento de um único período sem precisar especificá-lo toda vez:
def juros_compostos(capital, taxa, periodos=1):
montante = capital * (1 + taxa) ** periodos
rendimento = montante - capital
print(f"Capital inicial: R$ {capital:,.2f}")
print(f"Taxa por período: {taxa*100:.1f}%")
print(f"Períodos: {periodos}")
print(f"Rendimento: R$ {rendimento:,.2f}")
print(f"Montante final: R$ {montante:,.2f}")
print("--- Rendimento da poupança em 1 mês ---")
juros_compostos(capital=10_000, taxa=0.005) # usa o padrão periodos=1
print()
print("--- Rendimento do Tesouro Selic em 12 meses ---")
juros_compostos(capital=10_000, taxa=0.005, periodos=12)--- Rendimento da poupança em 1 mês ---
Capital inicial: R$ 10,000.00
Taxa por período: 0.5%
Períodos: 1
Rendimento: R$ 50.00
Montante final: R$ 10,050.00
--- Rendimento do Tesouro Selic em 12 meses ---
Capital inicial: R$ 10,000.00
Taxa por período: 0.5%
Períodos: 12
Rendimento: R$ 616.78
Montante final: R$ 10,616.78
5.3 Retornando valores
Até agora, nossas funções apenas exibiam resultados com print(). A palavra-chave return permite que uma função devolva um resultado para quem a chamou, possibilitando seu uso em expressões e cálculos posteriores.
Essa é uma das distinções mais importantes para iniciantes:
# Versão com print: o resultado é exibido, mas não pode ser reutilizado
def dobro_print(n):
print(n * 2)
# Versão com return: o resultado é devolvido e pode ser usado em cálculos
def dobro_return(n):
return n * 2
resultado_print = dobro_print(5) # exibe 10...
print(resultado_print) # ...mas a variável guarda None!
print()
resultado_return = dobro_return(5)
print(resultado_return) # 10
print(resultado_return + 3) # 13 — podemos continuar operando!10
None
10
13
print() vs. return
Use print() quando quiser apenas mostrar algo ao usuário. Use return quando quiser que a função produza um valor que será usado em outro lugar do programa. Para construir modelos econômicos com vários cálculos encadeados, return é indispensável.
5.3.1 Exemplo: encadeando cálculos
A modularização — dividir um problema em funções menores, cada uma fazendo uma coisa só — é uma das práticas mais importantes em programação. O exemplo abaixo calcula o salário líquido descontando INSS e IRPF, com cada etapa em sua própria função:
def calcular_inss(salario_bruto):
teto_inss = 8_475.55 # teto do INSS em 2026
salario_inss = min(salario_bruto, teto_inss)
faixas_inss = [
(1_621.00, 0.075),
(2_902.84, 0.09),
(4_354.27, 0.12),
(teto_inss, 0.14)
]
inss = 0
anterior = 0
for limite, aliquota in faixas_inss:
if salario_inss > limite:
inss += (limite - anterior) * aliquota
anterior = limite
else:
inss += (salario_inss - anterior) * aliquota
break
return inss
def calcular_irpf(base_irpf):
# Tabela mensal do IRPF vigente a partir de maio de 2025
faixas_irpf = [
(2_428.80, 0.00, 0.00),
(2_826.65, 0.075, 182.16),
(3_751.05, 0.15, 394.16),
(4_664.68, 0.225, 675.49),
(float("inf"), 0.275, 908.73),
]
irpf = 0
for limite, aliquota, deducao in faixas_irpf:
if base_irpf <= limite:
irpf = (base_irpf * aliquota) - deducao
break
return max(irpf, 0) # IR não pode ser negativo
def salario_liquido(salario_bruto):
desconto_inss = calcular_inss(salario_bruto)
base_irpf = salario_bruto - desconto_inss
desconto_irpf = calcular_irpf(base_irpf)
liquido = salario_bruto - desconto_inss - desconto_irpf
return liquido
# Testando para diferentes faixas salariais
salarios = [1_500, 3_000, 6_000, 12_000]
print(f"{'Salário Bruto':>16} | {'INSS':>10} | {'IRPF':>10} | {'Salário Líquido':>16}")
print("-" * 62)
for bruto in salarios:
inss = calcular_inss(bruto)
irpf = calcular_irpf(bruto - inss)
liquido = salario_liquido(bruto)
print(f"R$ {bruto:>12,.2f} | R$ {inss:>7,.2f} | R$ {irpf:>7,.2f} | R$ {liquido:>13,.2f}") Salário Bruto | INSS | IRPF | Salário Líquido
--------------------------------------------------------------
R$ 1,500.00 | R$ 112.50 | R$ 0.00 | R$ 1,387.50
R$ 3,000.00 | R$ 248.60 | R$ 24.20 | R$ 2,727.21
R$ 6,000.00 | R$ 641.51 | R$ 564.85 | R$ 4,793.63
R$ 12,000.00 | R$ 988.09 | R$ 2,119.54 | R$ 8,892.36
5.3.2 Múltiplos retornos
Uma função pode retornar mais de um valor separando-os por vírgula. O Python os agrupa em uma tupla, que pode ser desempacotada em variáveis distintas:
def operacoes(a, b):
soma = a + b
produto = a * b
return soma, produto
s, p = operacoes(2, 3)
print(s, p) # Saída: 5 65 6
Também é possível retornar dicionários, o que é especialmente útil quando os resultados têm nomes significativos:
import statistics
def descritivas(x):
media = statistics.mean(x)
desvio_padrao = statistics.stdev(x)
return {"media": media, "desvio_padrao": desvio_padrao}
dados = [1, 2, 3, 4, 5]
print(descritivas(dados)){'media': 3, 'desvio_padrao': 1.5811388300841898}
5.3.3 Exemplo: métricas de inflação
O exemplo abaixo calcula a inflação acumulada e a média mensal a partir de uma lista de taxas mensais, retornando ambas em uma única chamada:
def analisar_inflacao(taxas_mensais):
# Inflação acumulada: produto de (1 + taxa) para cada mês
acumulada = 1
for taxa in taxas_mensais:
acumulada *= (1 + taxa)
acumulada -= 1 # converte de volta para formato decimal
media_mensal = statistics.mean(taxas_mensais)
return acumulada, media_mensal
# IPCA mensal hipotético (em decimal)
ipca_2024 = [0.0042, 0.0083, 0.0016, 0.0038, 0.0044,
0.0050, 0.0038, 0.0044, 0.0044, 0.0056,
0.0039, 0.0052]
acum, media = analisar_inflacao(ipca_2024)
print(f"Inflação acumulada no ano: {acum*100:.2f}%")
print(f"Inflação média mensal: {media*100:.2f}%")Inflação acumulada no ano: 5.60%
Inflação média mensal: 0.46%
5.4 Aplicação: Teorema Central do Limite
No capítulo anterior, escrevemos um código para simular o Teorema Central do Limite (TCL): ao retirar muitas amostras de uma distribuição e calcular a média de cada uma, a distribuição dessas médias tende a ser normal — independentemente da distribuição original.
O código original funcionava, mas tinha uma limitação: os parâmetros da simulação estavam fixados diretamente no código. Para testar cenários diferentes, era preciso reescrevê-lo toda vez.
Transformar esse código em uma função reutilizável resolve o problema. Os parâmetros com valores padrão (n_amostras=10000, tamanho_amostra=30, seed=1234) deixam a função flexível: ela funciona sem nenhum argumento, mas também aceita configurações personalizadas.
import numpy as np
def simular_tcl(n_amostras=10000, tamanho_amostra=30, seed=1234):
"""
Simula o Teorema Central do Limite usando amostras de uma
distribuição uniforme entre 0 e 1.
Parâmetros:
n_amostras (int): número de amostras a gerar. Padrão: 10000.
tamanho_amostra (int): observações por amostra. Padrão: 30.
seed (int): semente para reprodutibilidade. Padrão: 1234.
Retorna:
float: média das médias amostrais.
"""
np.random.seed(seed)
medias = []
for _ in range(n_amostras):
amostra = np.random.uniform(0, 1, tamanho_amostra)
medias.append(np.mean(amostra))
return np.mean(medias)
resultado = simular_tcl()
print(f"Média das médias (padrão): {resultado:.4f}")Média das médias (padrão): 0.4994
5.4.1 Verificando a convergência
Uma das demonstrações clássicas do TCL é observar como a média das médias converge para o valor teórico (\(\mu = 0{,}5\) no caso da \(U(0,1)\)) conforme aumentamos o número de amostras. Com a função, isso fica muito mais claro:
lista_n_amostras = [1, 10, 100, 1_000, 10_000, 100_000]
print(f"{'Nº de amostras':>16} | {'Média das médias':>18} | {'Erro vs. 0.5':>14}")
print("-" * 56)
for n in lista_n_amostras:
media = simular_tcl(n_amostras=n, tamanho_amostra=5)
erro = abs(media - 0.5)
print(f"{n:>16,} | {media:>18.4f} | {erro:>14.4f}") Nº de amostras | Média das médias | Erro vs. 0.5
--------------------------------------------------------
1 | 0.5633 | 0.0633
10 | 0.5225 | 0.0225
100 | 0.5205 | 0.0205
1,000 | 0.4992 | 0.0008
10,000 | 0.5002 | 0.0002
100,000 | 0.4996 | 0.0004
Note que, ao aumentar o número de amostras, a média das médias se aproxima cada vez mais de 0,5 — exatamente o TCL em ação. E com a função, podemos explorar esse comportamento variando os parâmetros com apenas uma linha de código.
5.5 Docstrings
Docstrings são strings de documentação escritas logo abaixo do cabeçalho de uma função, entre aspas triplas ("""). Elas descrevem o que a função faz, quais parâmetros recebe e o que retorna.
Boas docstrings tornam o código muito mais fácil de entender e manter — especialmente quando você retorna a ele depois de semanas, ou quando compartilha com colegas. Você pode consultá-las a qualquer momento com help():
def taxa_desemprego(desempregados, populacao_ativa):
"""
Calcula a taxa de desemprego de uma economia.
Parâmetros:
desempregados (float): número de pessoas desempregadas.
populacao_ativa (float): tamanho da força de trabalho (PEA).
Retorna:
float: taxa de desemprego, expressa em percentual (%).
"""
return (desempregados / populacao_ativa) * 100
help(taxa_desemprego)Help on function taxa_desemprego in module __main__:
taxa_desemprego(desempregados, populacao_ativa)
Calcula a taxa de desemprego de uma economia.
Parâmetros:
desempregados (float): número de pessoas desempregadas.
populacao_ativa (float): tamanho da força de trabalho (PEA).
Retorna:
float: taxa de desemprego, expressa em percentual (%).
# Dados hipotéticos (em milhões de pessoas)
taxa = taxa_desemprego(desempregados=8.5, populacao_ativa=107.0)
print(f"Taxa de desemprego: {taxa:.1f}%")Taxa de desemprego: 7.9%
5.6 Escopo de variáveis
O escopo de uma variável se refere ao local onde ela é definida e onde pode ser acessada. Python segue a regra LEGB para resolver os nomes: procura primeiro no escopo Local, depois no Enclosing, depois no Global e por fim no Built-in.
5.6.1 Escopo local
Uma variável definida dentro de uma função existe apenas dentro dela:
def funcao_local():
mensagem = "Olá, Mundo!" # variável local
print(mensagem)
funcao_local() # funciona
print(mensagem) # NameError: não existe fora da funçãoOlá, Mundo!
--------------------------------------------------------------------------- NameError Traceback (most recent call last) Cell In[17], line 7 3 print(mensagem) 6 funcao_local() # funciona ----> 7 print(mensagem) # NameError: não existe fora da função NameError: name 'mensagem' is not defined
5.6.2 Escopo enclosing
Se uma função está dentro de outra, a interna pode acessar as variáveis da externa — mas não o contrário:
def funcao_externa():
mensagem = "Olá, Mundo!"
def funcao_interna():
print(mensagem) # acessa a variável da função externa
funcao_interna()
funcao_externa()Olá, Mundo!
5.6.3 Escopo global
Uma variável definida fora de todas as funções pode ser lida de qualquer lugar. No entanto, para modificá-la dentro de uma função, é necessário declará-la com a palavra-chave global.
Primeiro, a leitura sem problema:
poupanca = 1000
def banco():
print(f"Saldo atual: R$ {poupanca}") # lê a variável global
banco()Saldo atual: R$ 1000
Agora, a tentativa de modificação sem global:
poupanca = 1000
def deposito(n):
poupanca += n # UnboundLocalError!
deposito(500)--------------------------------------------------------------------------- UnboundLocalError Traceback (most recent call last) Cell In[20], line 6 3 def deposito(n): 4 poupanca += n # UnboundLocalError! ----> 6 deposito(500) Cell In[20], line 4, in deposito(n) 3 def deposito(n): ----> 4 poupanca += n UnboundLocalError: local variable 'poupanca' referenced before assignment
UnboundLocalError?
Ao encontrar poupanca += n, o Python interpreta poupanca como uma variável local da função — pois está sendo atribuída. Mas como ela ainda não tem valor local, o Python não sabe de onde buscá-la.
A solução é usar global para avisar ao Python que a variável em questão pertence ao escopo global:
poupanca = 1000
def deposito(n):
global poupanca
poupanca += n
def retirada(n):
global poupanca
poupanca -= n
def banco():
deposito(500)
retirada(200)
print(f"Saldo atual: R$ {poupanca}")
banco()Saldo atual: R$ 1300
global
Embora global resolva o problema, seu uso excessivo dificulta a leitura e a manutenção do código — fica difícil rastrear onde uma variável está sendo alterada. Em programas maiores, é preferível passar o valor como parâmetro e retorná-lo explicitamente. Você aprenderá formas mais robustas de gerenciar estado à medida que avançar no curso.
5.6.4 Escopo enclosing com nonlocal
A palavra-chave nonlocal funciona de forma similar a global, mas atua no escopo enclosing: permite que uma função interna modifique uma variável da função que a contém.
No exemplo abaixo, transacao precisa de nonlocal para incrementar o contador definido em registrar_transacoes:
def registrar_transacoes():
total_transacoes = 0
def transacao(descricao):
nonlocal total_transacoes
total_transacoes += 1
print(f" Transação {total_transacoes}: {descricao}")
transacao("Depósito de R$ 500")
transacao("Pagamento de boleto R$ 120")
transacao("Transferência de R$ 200")
print(f"Total de transações registradas: {total_transacoes}")
registrar_transacoes() Transação 1: Depósito de R$ 500
Transação 2: Pagamento de boleto R$ 120
Transação 3: Transferência de R$ 200
Total de transações registradas: 3
5.6.5 Escopo built-in
O escopo built-in contém os nomes pré-definidos do Python — funções como print, len, range e sum. Eles estão sempre disponíveis, em qualquer parte do código:
print(len("Python")) # len é uma função built-in6
5.7 args e kwargs
*args e **kwargs são formas flexíveis de passar múltiplos argumentos para uma função, permitindo lidar com quantidades variáveis de dados — algo bastante útil em modelos econômicos, onde o número de variáveis pode mudar.
Observe, por exemplo, a assinatura da função print:
print(*objects, sep=' ', end='\n', file=sys.stdout, flush=False)*objectsaceita qualquer número de argumentos posicionais:print("a", "b", "c").end='\n'é um argumento nomeado com valor padrão:print("texto", end="").
args e kwargs são convenções, não palavras reservadas
O que importa são os asteriscos: * coleta múltiplos argumentos posicionais em uma tupla, e ** coleta múltiplos argumentos nomeados em um dicionário. Você poderia escrever *numeros ou **indicadores com o mesmo resultado. args e kwargs são apenas o padrão adotado pela comunidade Python.
5.7.1 *args: múltiplos argumentos posicionais
def adicao(*args):
resultado = 0
for argumento in args:
resultado += argumento
return resultado
print(adicao(1, 2))
print(adicao(1, 2, 3, 4))
print(adicao(1, 2, 3, 4, 5, 6))3
10
21
5.7.1.1 Exemplo: PIB com composição variável
Uma das identidades macroeconômicas mais fundamentais é:
\[Y = C + I + G + (X - M)\]
onde \(C\) é o consumo das famílias, \(I\) o investimento, \(G\) os gastos do governo, \(X\) as exportações e \(M\) as importações. Em vez de repetir essa fórmula toda vez que precisarmos calculá-la, podemos encapsulá-la em uma função:
def calcular_pib(consumo, investimento, gastos_governo, exportacoes, importacoes):
pib = consumo + investimento + gastos_governo + (exportacoes - importacoes)
print(f"PIB calculado: R$ {pib:.2f} bilhões")
# Dados hipotéticos (em bilhões de R$)
calcular_pib(
consumo=4_800,
investimento=1_100,
gastos_governo=2_200,
exportacoes=1_600,
importacoes=1_400
)PIB calculado: R$ 8300.00 bilhões
Com *args, podemos criar uma função que soma todos os componentes do PIB, independentemente de quantos forem passados:
def calcular_pib(*componentes):
"""Soma todos os componentes do PIB passados como argumentos."""
return sum(componentes)
pib_simples = calcular_pib(4800, 2200, 1600) # C + I + G
pib_completo = calcular_pib(4800, 1100, 2200, 1600, -1400) # C+ I + G + (X - M)
print(f"PIB simplificado: R$ {pib_simples:,.0f} bi")
print(f"PIB completo: R$ {pib_completo:,.0f} bi")PIB simplificado: R$ 8,600 bi
PIB completo: R$ 8,300 bi
5.7.2 **kwargs: múltiplos argumentos nomeados
**kwargs agrupa os argumentos passados com nome em um dicionário dentro da função:
def concatenar(**kwargs):
print(f"Valores recebidos: {kwargs}")
resultado = ""
for valor in kwargs.values():
resultado += f"{valor} "
return resultado
print(concatenar(curso="Economia"))
print(concatenar(curso="Economia", faculdade="FEA-USP"))Valores recebidos: {'curso': 'Economia'}
Economia
Valores recebidos: {'curso': 'Economia', 'faculdade': 'FEA-USP'}
Economia FEA-USP
5.7.2.1 Exemplo: relatório de indicadores macroeconômicos
Com **kwargs, podemos gerar relatórios com qualquer conjunto de variáveis — útil quando comparamos países com disponibilidades de dados diferentes:
def relatorio_macro(pais, **indicadores):
"""
Exibe um relatório de indicadores macroeconômicos.
Parâmetros:
pais (str): nome do país.
**indicadores: pares nome=valor para qualquer indicador econômico.
"""
print(f"\n=== Indicadores Macroeconômicos: {pais} ===")
for indicador, valor in indicadores.items():
nome_formatado = indicador.replace("_", " ").title()
print(f" {nome_formatado}: {valor}")
relatorio_macro(
"Brasil",
pib_crescimento="2.9%",
inflacao_ipca="4.83%",
taxa_desemprego="6.2%",
taxa_selic="10.5%"
)
relatorio_macro(
"Argentina",
inflacao="211%",
taxa_desemprego="7.7%"
)
=== Indicadores Macroeconômicos: Brasil ===
Pib Crescimento: 2.9%
Inflacao Ipca: 4.83%
Taxa Desemprego: 6.2%
Taxa Selic: 10.5%
=== Indicadores Macroeconômicos: Argentina ===
Inflacao: 211%
Taxa Desemprego: 7.7%
5.7.3 Combinando *args e **kwargs
def relatorio_economico(*args, **kwargs):
print("Valores agregados:", sum(args))
for chave, valor in kwargs.items():
print(f"{chave}: {valor}")
relatorio_economico(100, 200, consumo=5_000, investimento=2_000)Valores agregados: 300
consumo: 5000
investimento: 2000
5.8 Funções anônimas (lambda)
Funções lambda são funções anônimas — definidas sem nome, em uma única linha. São úteis para operações simples e temporárias, especialmente como argumento para outras funções. A sintaxe é:
lambda <argumentos> : <expressão>Um exemplo simples:
soma = lambda x, y: x + y
print(soma(5, 3))8
5.8.1 Função map()
map() aplica uma função a cada elemento de uma sequência. Com lambda, isso fica muito conciso:
numeros = [1, 2, 3, 4, 5]
quadrados = list(map(lambda x: x ** 2, numeros))
print(quadrados)[1, 4, 9, 16, 25]
5.8.1.1 Exemplo: corrigindo preços pela inflação
Em economia, deflacionar uma série de preços significa remover o efeito da inflação para tornar valores de diferentes períodos comparáveis em termos reais. A fórmula geral é:
\[P_{\text{real}} = \frac{P_{\text{nominal}}}{1 + \pi}\]
onde \(P_{\text{nominal}}\) é o preço observado no período e \(\pi\) é a taxa de inflação acumulada entre o período de referência e o período de base. O denominador \((1 + \pi)\) atua como um deflator: quanto maior a inflação, mais o preço nominal é “encolhido” para revelar seu valor real.
Um valor nominal é expresso nos preços correntes do período em que foi medido. Um valor real é corrigido pela inflação e expressa o poder de compra em termos de um período de referência (base). A distinção é fundamental em macroeconomia: o PIB pode crescer em termos nominais simplesmente porque os preços subiram, sem que haja crescimento real da produção.
No código abaixo, aplicamos a fórmula a cada preço da lista usando map() com uma função lambda — um caso típico em que lambda é mais conciso do que definir uma função completa com def:
precos_nominais = [10.00, 12.50, 9.80, 15.00, 11.30]
inflacao_acumulada = 0.15 # 15% de inflação acumulada no período
precos_reais = list(map(lambda p: p / (1 + inflacao_acumulada), precos_nominais))
print("Preço nominal -> Preço real (deflacionado)")
for nominal, real in zip(precos_nominais, precos_reais):
print(f" R$ {nominal:.2f} -> R$ {real:.2f}")Preço nominal -> Preço real (deflacionado)
R$ 10.00 -> R$ 8.70
R$ 12.50 -> R$ 10.87
R$ 9.80 -> R$ 8.52
R$ 15.00 -> R$ 13.04
R$ 11.30 -> R$ 9.83
5.8.2 Função filter()
filter() seleciona os elementos de uma sequência que satisfazem um critério booleano:
numeros = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
numeros_pares = list(filter(lambda x: x % 2 == 0, numeros))
print(numeros_pares)[2, 4, 6, 8, 10]
5.8.2.1 Exemplo: países com inflação acima da meta
paises_inflacao = [
("Brasil", 4.8),
("Chile", 3.2),
("Argentina", 211.0),
("México", 4.7),
("Colômbia", 9.3),
("Peru", 2.9),
("Uruguai", 5.1),
]
meta_inflacao = 4.5
acima_da_meta = list(filter(lambda x: x[1] > meta_inflacao, paises_inflacao))
print(f"Países com inflação acima de {meta_inflacao}%:")
for pais, inf in acima_da_meta:
print(f" {pais}: {inf}%")Países com inflação acima de 4.5%:
Brasil: 4.8%
Argentina: 211.0%
México: 4.7%
Colômbia: 9.3%
Uruguai: 5.1%
5.8.3 Função sorted()
sorted() ordena sequências. O parâmetro key aceita uma função que define o critério de ordenamento.
.items()
Dicionários em Python armazenam pares chave: valor. O método .items() retorna esses pares como uma sequência de tuplas (chave, valor), o que permite iterá-los e ordená-los como qualquer outra sequência.
# Ordenando uma lista de tuplas pelo segundo elemento
minha_lista = [("maçã", 1), ("banana", 3), ("laranja", 2)]
minha_lista_ordenada = sorted(minha_lista, key=lambda x: x[1])
print(minha_lista_ordenada)
# Ordenando um dicionário pelos valores (de maior para menor)
notas = {"Danilo": 7, "Mariana": 9, "Bruno": 4, "Daniela": 8.5}
notas_ordenadas = sorted(
notas.items(), # retorna [(chave, valor), ...]
key=lambda x: x[1], # ordena pelo valor (segundo elemento de cada tupla)
reverse=True
)
print(notas_ordenadas)[('maçã', 1), ('laranja', 2), ('banana', 3)]
[('Mariana', 9), ('Daniela', 8.5), ('Danilo', 7), ('Bruno', 4)]
5.8.3.1 Exemplo: ranking de países por PIB per capita
# (país, PIB per capita em US$ mil, taxa de desemprego em %)
paises = [
("Brasil", 9.0, 6.2),
("Argentina", 11.6, 7.7),
("Chile", 16.5, 8.9),
("México", 10.8, 2.7),
("Colômbia", 6.8, 9.1),
("Peru", 6.6, 7.4),
]
# Por PIB per capita (maior → menor)
ranking_pib = sorted(paises, key=lambda x: x[1], reverse=True)
print("Ranking por PIB per capita (US$ mil):")
for i, (pais, pib, _) in enumerate(ranking_pib, start=1):
print(f" {i}º {pais}: US$ {pib:.1f} mil")
print()
# Por taxa de desemprego (menor → maior)
ranking_desemp = sorted(paises, key=lambda x: x[2])
print("Ranking por taxa de desemprego (menor → maior):")
for i, (pais, _, desemp) in enumerate(ranking_desemp, start=1):
print(f" {i}º {pais}: {desemp}%")Ranking por PIB per capita (US$ mil):
1º Chile: US$ 16.5 mil
2º Argentina: US$ 11.6 mil
3º México: US$ 10.8 mil
4º Brasil: US$ 9.0 mil
5º Colômbia: US$ 6.8 mil
6º Peru: US$ 6.6 mil
Ranking por taxa de desemprego (menor → maior):
1º México: 2.7%
2º Brasil: 6.2%
3º Peru: 7.4%
4º Argentina: 7.7%
5º Chile: 8.9%
6º Colômbia: 9.1%
💡 Sobre a função enumerate()
A função enumerate() permite percorrer uma lista obtendo ao mesmo tempo o índice e o valor de cada elemento. No exemplo, ela é usada para gerar automaticamente a posição no ranking (1º, 2º, etc.), começando em 1 com o parâmetro start=1, sem precisar controlar manualmente um contador.
5.9 Exercícios
Escreva uma função
variacao_percentual(valor_inicial, valor_final)que calcule a variação percentual entre dois valores. Aplique-a para calcular a variação do IPCA entre dois anos hipotéticos e a variação do PIB real entre dois trimestres.Usando as funções
calcular_inssecalcular_irpfdefinidas neste capítulo, escreva uma funçãoaliquota_efetiva(salario_bruto)que retorne a alíquota efetiva total (INSS + IRPF como percentual do salário bruto). Exiba a alíquota efetiva para os salários[2_000, 5_000, 10_000, 20_000]e comente o que você observa.Escreva uma função
elasticidade_preco(q1, q2, p1, p2)que calcule a elasticidade-preço da demanda pela fórmula:
\[\varepsilon = \frac{\Delta Q / Q_1}{\Delta P / P_1}\]
Teste a função com os seguintes dados: quando o preço de um bem passa de R$10 para R$12, a quantidade demandada cai de 100 para 80 unidades. Interprete o resultado.
Considere a lista de países e seus respectivos PIBs per capita (em US$ mil):
[("Brasil", 9.0), ("Chile", 16.5), ("Argentina", 11.6), ("México", 10.8), ("Peru", 6.6), ("Colômbia", 6.8)]. Utilizandofilter()emap()com funções lambda:- Filtre apenas os países com PIB per capita acima de US$ 10 mil.
- Para os países filtrados, crie uma nova lista com o PIB per capita convertido para reais (use a taxa de câmbio de R$ 5,80/US$).
Expanda a função
simular_tcl()definida neste capítulo para aceitar também o parâmetrodistribuicao, que pode ser"uniforme"ou"exponencial". Usenp.random.uniform(0, 1, n)para a distribuição uniforme enp.random.exponential(scale=1, size=n)para a exponencial. Verifique se a média das médias converge para o valor teórico esperado em cada caso (\(\mu = 0{,}5\) para a uniforme e \(\mu = 1\) para a exponencial comscale=1).