Este guia prático de Python visa consolidar conhecimentos essenciais para resolução ágil de problemas em ambientes de codificação, especialmente onde o tempo é um fator crítico. Foca nas funcionalidades básicas da linguagem e estruturas de dados.
Ferramentas Úteis para Exploração
Em ambientes restritos ou sem acesso a uma IDE completa, conhecer as funções de introspecção do Python pode ser muito útil para descobrir métodos e atributos de objetos:
# Exibe todos os métodos e atributos de um dicionário
print(dir(dict))
# Saída: ['__class__', ..., 'clear', 'copy', 'fromkeys', 'get', 'items', 'keys', 'pop', 'popitem', 'setdefault', 'update', 'values']
# Obtém a documentação de uma função específica, como 'get' de um dicionário
print(help(dict.get))
# Saída:
# Help on method_descriptor:
# get(self, key, default=None, /)
# Return the value for key if key is in the dictionary, else default.
# None
Fundamentos de Python
1. Entrada de Dados
A função input() lê uma linha de texto do console. Por padrão, o valor retornado é uma string. Para utilizar como outros tipos, é necesário realizar a conversão explícita.
# Lê uma string
nome_usuario = input("Digite seu nome: ")
print(f"Olá, {nome_usuario}!")
# Converte a entrada para um número inteiro
idade = int(input("Qual é a sua idade? "))
print(f"Você tem {idade} anos.")
# Lê múltiplos inteiros em uma única linha, separados por espaço
# e os atribui a variáveis distintas
num1, num2 = map(int, input("Digite dois números separados por espaço: ").split())
print(f"Primeiro número: {num1}, Segundo número: {num2}")
# Lê uma sequência de inteiros em uma linha e os armazena em uma lista
valores_lidos = list(map(int, input("Digite vários números separados por espaço: ").split()))
print(f"Lista de valores: {valores_lidos}")
2. Saída de Dados
A função print() exibe enformações no console. Por padrão, adiciona uma nova linha ao final. É possível modificar esse comportamento e usar separadores personalizados.
# Saída básica
mensagem = "Boas-vindas ao Python!"
print(mensagem)
# Saída com múltiplos argumentos, separados por espaço (padrão)
print("A", "linguagem", "Python")
# Personalizando o separador entre os argumentos
print("data", "hora", "minuto", sep=":") # Saída: data:hora:minuto
# Evitando a quebra de linha padrão no final
print("Esta é a primeira parte...", end=" ")
print("e esta é a segunda parte na mesma linha.")
# Saída formatada usando f-strings (Python 3.6+)
produto = "notebook"
preco = 1250.75
print(f"O preço do {produto} é R$ {preco:.2f}.")
# Conversão ASCII
print(f"O código ASCII de 'Z' é {ord('Z')}.") # Saída: O código ASCII de 'Z' é 90.
print(f"O caractere para o código 97 é '{chr(97)}'.") # Saída: O caractere para o código 97 é 'a'.
# Gravando saída em um arquivo
# O modo 'w' cria ou sobrescreve o arquivo, 'a' anexa
caminho_arquivo = "saida_log.txt"
with open(caminho_arquivo, 'w', encoding='utf-8') as arq:
print("Este texto será gravado no arquivo.", file=arq)
print("Outra linha de conteúdo.", file=arq)
Uma técnica útil para exibir elementos de listas:
# Exemplo prático de saída de lista
lista_resultados = [10, 20, 30, 40, 50]
# Une os elementos da lista em uma única string, separados por vírgula
print(",".join(str(item) for item in lista_resultados)) # Saída: 10,20,30,40,50
3. Tipos de Dados Fundamentais
Python possui vários tipos de dados, alguns mutáveis (cujo conteúdo pode ser alterado após a criação) e outros imutáveis.
- Numéricos (int, float, complex): Imutáveis
- Strings (str): Imutáveis
- Booleanos (bool): Imutáveis (mas geralmente tratados como numéricos 0 e 1)
- Listas (list): Mutáveis
- Tuplas (tuple): Imutáveis
- Conjuntos (set): Mutáveis
- Dicionários (dict): Mutáveis
Operadores Aritméticos e de Bit
Python suporta os operadores aritméticos comuns, além de operadores de bit.
# Operadores Aritméticos
a, b = 10, 3
print(f"Soma: {a + b}") # 13
print(f"Subtração: {a - b}") # 7
print(f"Multiplicação: {a * b}") # 30
print(f"Divisão: {a / b}") # 3.333... (float)
print(f"Divisão inteira: {a // b}") # 3 (arredonda para baixo)
print(f"Módulo (resto): {a % b}") # 1
print(f"Potenciação: {a ** b}") # 10^3 = 1000
# Notação científica
valor_grande = 3.5e4 # 3.5 * 10^4 = 35000.0
print(f"Valor científico: {valor_grande}")
# Operadores de Bit
x, y = 6, 11 # Binário: x=0b0110, y=0b1011
print(f"AND de bits (x & y): {x & y}") # 0b0010 = 2
print(f"OR de bits (x | y): {x | y}") # 0b1111 = 15
print(f"XOR de bits (x ^ y): {x ^ y}") # 0b1101 = 13
print(f"Negação de bits (~x): {~x}") # -7 (equivalente a -(x+1))
print(f"Deslocamento à direita (x >> 1): {x >> 1}") # 0b0011 = 3 (equivalente a x // 2)
print(f"Deslocamento à esquerda (y << 2): {y << 2}") # 0b101100 = 44 (equivalente a y * 2**2)
# Cadeia de comparações
val = 8
print(f"3 < val < 10 é {3 < val < 10}") # True
Conversão de Bases Numéricas:
# Convertendo strings de diferentes bases para inteiro (base 10)
print(f"int('101', 2): {int('101', 2)}") # Binário '101' para 5
print(f"int('13', 8): {int('13', 8)}") # Octal '13' para 11
print(f"int('A', 16): {int('A', 16)}") # Hexadecimal 'A' para 10
# Convertendo inteiros (base 10) para strings de outras bases
print(f"bin(7): {bin(7)}") # Inteiro 7 para binário '0b111'
print(f"oct(15): {oct(15)}") # Inteiro 15 para octal '0o17'
print(f"hex(255): {hex(255)}") # Inteiro 255 para hexadecimal '0xff'
# Conversão de volta para int a partir de strings binárias/octais/hexadecimais
numero_binario_str = bin(9) # '0b1001'
print(f"int(numero_binario_str, 2): {int(numero_binario_str, 2)}") # 9
Strings (str)
Strings são sequências de caracteres imutáveis.
# Declaração de string
minha_frase = "Programação em Python"
# Acessando caracteres (indexação)
print(f"Primeiro caractere: {minha_frase[0]}") # P
print(f"Último caractere: {minha_frase[-1]}") # n
# Fatiamento (slicing)
# string[start:end:step]
parte = minha_frase[0:11] # "Programação"
print(f"Fatiamento: {parte}")
# Invertendo uma string
frase_invertida = minha_frase[::-1]
print(f"String invertida: {frase_invertida}") # nohtyP me oãçamargorP
# Concatenação
saudacao = "Olá" + " " + "Mundo!"
print(f"Concatenação: {saudacao}")
# Repetição
repeticao = "abc" * 3
print(f"Repetição: {repeticao}") # abcabcabc
# Verificando existência de substring
print(f"'Python' está em minha_frase: {'Python' in minha_frase}") # True
Listas (list)
Listas são coleções ordenadas e mutáveis de itens.
# Inicialização
lista_vazia = []
lista_numeros = [10, 20, 30, 40]
# Adicionando elementos
lista_numeros.append(50) # Adiciona no final: [10, 20, 30, 40, 50]
lista_numeros.insert(0, 5) # Insere na posição 0: [5, 10, 20, 30, 40, 50]
# Removendo elementos
lista_numeros.remove(20) # Remove a primeira ocorrência do valor 20: [5, 10, 30, 40, 50]
elemento_removido = lista_numeros.pop() # Remove e retorna o último: 50, lista: [5, 10, 30, 40]
lista_numeros.pop(1) # Remove e retorna o elemento no índice 1 (10): [5, 30, 40]
del lista_numeros[0] # Remove o elemento no índice 0 (5): [30, 40]
# lista_numeros.clear() # Esvazia a lista: []
# Acessando elementos
minha_lista = [1, 2, 3, 4, 5]
print(f"Primeiro elemento: {minha_lista[0]}") # 1
print(f"Último elemento: {minha_lista[-1]}") # 5
# Fatiamento (slicing)
sub_lista = minha_lista[1:4] # [2, 3, 4] (do índice 1 ao 3)
print(f"Sub-lista: {sub_lista}")
# Fatiamento com passo
lista_original = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
passo_dois = lista_original[::2] # [1, 3, 5, 7, 9]
invertida_passo_um = lista_original[::-1] # [10, 9, 8, 7, 6, 5, 4, 3, 2, 1]
print(f"Lista com passo 2: {passo_dois}")
print(f"Lista invertida: {invertida_passo_um}")
# Copiando listas (cópia rasa vs. cópia profunda)
lista_a = [1, 2, [3, 4]]
lista_b = lista_a.copy() # Cópia rasa
lista_b[0] = 100
lista_b[2][0] = 300 # Isso altera lista_a também!
print(f"Lista A após cópia rasa: {lista_a}") # [1, 2, [300, 4]]
print(f"Lista B após cópia rasa: {lista_b}") # [100, 2, [300, 4]]
import copy
lista_c = copy.deepcopy(lista_a) # Cópia profunda
lista_c[2][0] = 333
print(f"Lista A após cópia profunda: {lista_a}") # [1, 2, [300, 4]] (não foi alterada por lista_c)
print(f"Lista C após cópia profunda: {lista_c}") # [1, 2, [333, 4]]
# Operações com listas
outra_lista = [6, 7]
lista_concatenada = minha_lista + outra_lista # [1, 2, 3, 4, 5, 6, 7]
lista_repetida = [0] * 3 # [0, 0, 0]
# Informações da lista
print(f"Tamanho da lista: {len(minha_lista)}")
print(f"Maior elemento: {max(minha_lista)}")
print(f"Menor elemento: {min(minha_lista)}")
print(f"Soma dos elementos: {sum(minha_lista)}")
print(f"Contagem de '3': {minha_lista.count(3)}")
# Busca
print(f"Índice de '3': {minha_lista.index(3)}") # Retorna o índice da primeira ocorrência
print(f"O valor 10 está na lista: {10 in minha_lista}") # False
# Ordenação
lista_desordenada = [5, 1, 4, 2, 8]
lista_desordenada.sort() # Ordena a lista in-place: [1, 2, 4, 5, 8]
lista_ordenada_nova = sorted([9, 3, 7, 6]) # Retorna uma nova lista ordenada: [3, 6, 7, 9]
lista_desordenada.reverse() # Inverte a ordem in-place: [8, 5, 4, 2, 1]
# Iteração
for elemento in minha_lista:
print(f"Elemento: {elemento}")
for indice, valor in enumerate(minha_lista):
print(f"Índice: {indice}, Valor: {valor}")
# Comparação de listas
import operator
lista_x = [1, 2, 3]
lista_y = [1, 2, 3]
lista_z = [3, 2, 1]
print(f"lista_x == lista_y: {operator.eq(lista_x, lista_y)}") # True
print(f"lista_x == lista_z: {operator.eq(lista_x, lista_z)}") # False
Conjuntos (set)
Conjuntos são coleções não ordenadas de itens únicos e mutáveis. Úteis para operações de união, interseção, diferença.
# Inicialização
conjunto_vazio = set()
meu_conjunto = {1, 2, 3, 4, 5}
print(f"Conjunto a partir de lista: {set([5, 1, 5, 2, 3])}") # {1, 2, 3, 5} (elementos duplicados são removidos)
# Adicionando elementos
meu_conjunto.add(6) # {1, 2, 3, 4, 5, 6}
meu_conjunto.update([7, 8]) # Adiciona múltiplos elementos: {1, ..., 8}
# Removendo elementos
meu_conjunto.remove(1) # Remove '1'. Se '1' não existe, gera erro.
meu_conjunto.discard(99) # Tenta remover '99'. Não faz nada se não existe.
elemento_aleatorio = meu_conjunto.pop() # Remove e retorna um elemento arbitrário. Gera erro se vazio.
# meu_conjunto.clear() # Remove todos os elementos.
# Operações de Conjunto
c1 = {1, 2, 3, 4, 5}
c2 = {4, 5, 6, 7, 8}
print(f"Interseção (c1 & c2): {c1 & c2}") # {4, 5}
print(f"União (c1 | c2): {c1 | c2}") # {1, 2, 3, 4, 5, 6, 7, 8}
print(f"Diferença (c1 - c2): {c1 - c2}") # {1, 2, 3}
print(f"Diferença simétrica (c1 ^ c2): {c1 ^ c2}") # {1, 2, 3, 6, 7, 8}
# Verificando relações entre conjuntos
c_maior = {1, 2, 3, 4}
c_menor = {1, 2}
print(f"c_menor é subconjunto de c_maior: {c_menor.issubset(c_maior)}") # True
print(f"c_maior é superconjunto de c_menor: {c_maior.issuperset(c_menor)}") # True
# Conjunto imutável (frozenset)
conjunto_imutavel = frozenset(['a', 'b', 'c'])
# conjunto_imutavel.add('d') # Isso geraria um erro
Tuplas (tuple)
Tuplas são coleções ordenadas e imutáveis de itens. São semelhantes às listas, mas não podem ser modificadas após a criação.
# Inicialização
minha_tupla = (10, "Python", 3.14)
tupla_singleton = (42,) # Vírgula é essencial para tuplas de um único item
print(f"Tipo da tupla singleton: {type(tupla_singleton)}") # <class 'tuple'>
# Acessando elementos
print(f"Primeiro elemento da tupla: {minha_tupla[0]}") # 10
# Fatiamento (slicing)
sub_tupla = minha_tupla[1:]
print(f"Sub-tupla: {sub_tupla}") # ('Python', 3.14)
# Tentativa de modificação (resulta em erro)
# minha_tupla[0] = 20 # TypeError: 'tuple' object does not support item assignment
# Iteração
for item in minha_tupla:
print(f"Item da tupla: {item}")
for idx, val in enumerate(minha_tupla):
print(f"Índice: {idx}, Valor: {val}")
Dicionários (dict)
Dicionários são coleções não ordenadas e mutáveis de pares chave-valor. As chaves devem ser únicas e imutáveis.
# Inicialização
dicionario_vazio = {}
precos_frutas = {"maçã": 2.50, "banana": 1.75, "laranja": 1.20}
# Adicionando/Atualizando elementos
precos_frutas["uva"] = 4.00 # Adiciona um novo par
precos_frutas["maçã"] = 2.75 # Atualiza o valor da chave 'maçã'
# Acessando valores
print(f"Preço da banana: {precos_frutas['banana']}") # 1.75
# Usando .get() para evitar KeyError se a chave não existir
print(f"Preço do abacaxi: {precos_frutas.get('abacaxi', 'Não disponível')}") # Não disponível
# Removendo elementos
del precos_frutas["laranja"] # Remove o par com a chave 'laranja'
valor_removido = precos_frutas.pop("uva") # Remove e retorna o valor da chave 'uva'
item_removido = precos_frutas.popitem() # Remove e retorna um par (chave, valor) arbitrário (geralmente o último inserido antes de 3.7)
# precos_frutas.clear() # Esvazia o dicionário
# Copiando dicionários (cópia rasa)
dicionario_copia = precos_frutas.copy()
# Chaves, Valores e Itens
chaves = list(precos_frutas.keys()) # Retorna uma lista das chaves
valores = list(precos_frutas.values()) # Retorna uma lista dos valores
itens = list(precos_frutas.items()) # Retorna uma lista de tuplas (chave, valor)
print(f"Chaves: {chaves}") # ['maçã', 'banana']
print(f"Valores: {valores}") # [2.75, 1.75]
print(f"Itens: {itens}") # [('maçã', 2.75), ('banana', 1.75)]
# Iteração
for fruta, preco in precos_frutas.items():
print(f"Fruta: {fruta}, Preço: {preco}")
# Iterando apenas sobre as chaves
for fruta in precos_frutas: # Ou precos_frutas.keys()
print(f"Fruta: {fruta}")
# Ordenando dicionário pelas chaves (retorna uma lista de valores ordenados)
dicionario_aleatorio = {3: "c", 1: "a", 2: "b"}
valores_ordenados = [dicionario_aleatorio[chave] for chave in sorted(dicionario_aleatorio.keys())]
print(f"Valores ordenados por chave: {valores_ordenados}") # ['a', 'b', 'c']