Strings avançado
Esta aula aprofunda o uso de strings em Python, abordando formatação com f-strings e format(), imutabilidade e suas implicações, encoding e diferença entre str e bytes, além de operações comuns como split, join e strip. O conteúdo inclui exemplos práticos e exercícios com respostas.
Nesta aula, vamos explorar tópicos avançados sobre strings em Python, essenciais para manipulação eficiente de texto. Você aprenderá como formatar strings de diferentes maneiras, entenderá por que strings são imutáveis e como isso afeta o desempenho, compreenderá a diferença entre str e bytes no contexto de encoding, e dominará operações comuns do dia a dia.
Strings são um dos tipos mais versáteis em Python. Dominar esses conceitos permitirá que você escreva código mais limpo, eficiente e preparado para lidar com diferentes codificações de caracteres.
Formatação
A formatação de strings permite inserir valores dinâmicos em um template de texto. Python oferece três principais formas: operador %, método str.format() e f-strings (Python 3.6+). As f-strings são as mais modernas e recomendadas por sua legibilidade e desempenho.
Exemplo com f-strings:
nome = "Maria"
idade = 30
print(f"Olá, {nome}! Você tem {idade} anos.")
# Saída: Olá, Maria! Você tem 30 anos.É possível usar expressões dentro das chaves:
a, b = 10, 3
print(f"{a} dividido por {b} é {a/b:.2f}")
# Saída: 10 dividido por 3 é 3.33O método str.format() é útil quando a string de formato é definida em outro lugar:
template = "Olá, {nome}! Você tem {idade} anos."
print(template.format(nome="João", idade=25))
# Saída: Olá, João! Você tem 25 anos.O operador % é mais antigo, mas ainda aparece em código legado:
print("Olá, %s! Você tem %d anos." % ("Ana", 22))
# Saída: Olá, Ana! Você tem 22 anos.Imutabilidade
Strings em Python são imutáveis, ou seja, uma vez criadas, não podem ser alteradas. Qualquer operação que parece modificar uma string na verdade cria uma nova string. Isso tem implicações importantes na memória e desempenho.
Exemplo de imutabilidade:
s = "hello"
# s[0] = 'H' # Isso gera TypeError: 'str' object does not support item assignment
s = "H" + s[1:] # Cria uma nova string
print(s) # "Hello"Por serem imutáveis, strings podem ser usadas como chaves em dicionários e elementos de conjuntos. Além disso, o Python otimiza o uso de memória para strings pequenas (internamento), mas isso é transparente para o programador.
Concatenação repetida em loops pode ser ineficiente, pois cria várias strings intermediárias. Prefira usar listas e str.join():
# Ineficiente
s = ""
for i in range(1000):
s += str(i)
# Eficiente
partes = [str(i) for i in range(1000)]
s = "".join(partes)Encoding (str vs bytes)
Em Python, strings (str) representam texto Unicode, enquanto bytes representam dados binários. Encoding é o processo de converter str para bytes, e decoding é o inverso. Os métodos encode() e decode() são usados para isso.
Exemplo de encoding e decoding:
texto = "Olá, mundo!"
# Converter para bytes usando UTF-8 (padrão)
dados = texto.encode('utf-8')
print(dados) # b'Ol\xc3\xa1, mundo!'
print(type(dados)) #
# Voltar para string
texto2 = dados.decode('utf-8')
print(texto2) # Olá, mundo! É importante usar a mesma codificação em ambos os lados. Erros comuns incluem tentar decodificar bytes com encoding errado, resultando em UnicodeDecodeError. Use o parâmetro errors para lidar com isso:
dados = b'Ol\xe1, mundo!' # Latin-1
print(dados.decode('utf-8', errors='replace')) # Substitui caracteres inválidosA diferença entre str e bytes é crucial ao trabalhar com arquivos binários, redes ou bibliotecas que exigem bytes (ex.: hashlib, sockets).
Operações comuns
Strings possuem diversos métodos úteis. Vamos revisar alguns dos mais importantes.
split() e join(): split() divide uma string em lista com base em um separador; join() une uma lista de strings em uma única string.
frase = "Python é uma linguagem poderosa"
palavras = frase.split() # ['Python', 'é', 'uma', 'linguagem', 'poderosa']
print(palavras)
# join
frase2 = " ".join(palavras)
print(frase2) # Python é uma linguagem poderosa
# split com separador específico
dados = "nome:João,idade:30"
print(dados.split(',')) # ['nome:João', 'idade:30']strip(), lstrip(), rstrip(): removem caracteres em branco (ou outros) do início/fim.
texto = " Olá, mundo! "
print(texto.strip()) # "Olá, mundo!"
print(texto.lstrip()) # "Olá, mundo! "
print(texto.rstrip()) # " Olá, mundo!"
# Removendo caracteres específicos
print("...Hello...".strip('.')) # "Hello"find() e index(): localizam substrings. find() retorna -1 se não encontrar; index() levanta exceção.
s = "Python é legal"
print(s.find('é')) # 7
print(s.find('Java')) # -1
print(s.index('é')) # 7
# print(s.index('Java')) # ValueErrorreplace(): substitui ocorrências de uma substring por outra.
s = "gato, gato, cachorro"
print(s.replace('gato', 'rato')) # "rato, rato, cachorro"
print(s.replace('gato', 'rato', 1)) # "rato, gato, cachorro"startswith() e endswith(): verificam prefixo/sufixo.
arquivo = "documento.pdf"
print(arquivo.endswith('.pdf')) # True
print(arquivo.startswith('doc')) # Truecount(): conta ocorrências não sobrepostas.
texto = "banana"
print(texto.count('ana')) # 1 (não sobrepõe)
print(texto.count('a')) # 3Boas práticas
Prefira f-strings para formatação simples. Use str.join() para concatenar muitas strings. Sempre especifique o encoding ao ler/escrever arquivos de texto (encoding='utf-8'). Evite usar + em loops para concatenar strings. Para verificar se uma substring está presente, use o operador 'in' em vez de find(): 'sub' in string.
Referências
- Documentação oficial: str
- Formatando saída (tutorial oficial)
- string — Formatação de strings
- Unicode HOWTO
- Real Python: Python Strings
Exercícios
Escreva uma função que receba um nome e uma idade e retorne uma string formatada: "Olá, [nome]! Você tem [idade] anos." usando f-string.
✓ Resposta:def saudacao(nome, idade): return f"Olá, {nome}! Você tem {idade} anos."Explique por que o código abaixo é ineficiente e sugira uma melhoria:
s = "" for i in range(10000): s += str(i)✓ Resposta:O código é ineficiente porque strings são imutáveis: a cada iteração, uma nova string é criada, copiando o conteúdo anterior, resultando em O(n²) de complexidade. Melhoria: usar uma lista e depois join.
partes = [str(i) for i in range(10000)] s = "".join(partes)Converta a string "Olá, mundo!" para bytes usando UTF-8 e depois decodifique de volta. Mostre o resultado.
✓ Resposta:texto = "Olá, mundo!" dados = texto.encode('utf-8') print(dados) # b'Ol\xc3\xa1, mundo!' texto2 = dados.decode('utf-8') print(texto2) # Olá, mundo!Dada a string " Python é legal! ", remova os espaços das extremidades e depois substitua "legal" por "poderoso".
✓ Resposta:s = " Python é legal! " s = s.strip() s = s.replace('legal', 'poderoso') print(s) # Python é poderoso!Conte quantas vezes a letra 'a' aparece na string "banana" e verifique se a string começa com 'b'.
✓ Resposta:texto = "banana" print(texto.count('a')) # 3 print(texto.startswith('b')) # True