Strings e Containers Abrangente

Nas lições anteriores, cobrimos listas, tuplas, dicionários, conjuntos e métodos de string. Agora vamos combiná-los — usando as "combinações" mais comuns para resolver problemas reais. Estas técnicas são usadas diariamente na programação profissional.


1. split() Trabalhando com Listas

split() quebra uma string em uma lista — o primeiro passo no processamento de dados:

PYTHON
# Análise de dados CSV
line = "Alice,25,São Paulo,Engenheira"
fields = line.split(",")
print(fields)               # ['Alice', '25', 'São Paulo', 'Engenheira']

# Dividir por espaços em branco (padrão)
text = "hello   world    python"
words = text.split()
print(words)                # ['hello', 'world', 'python']

# Limitar o número de divisões
data = "2026-06-23-15-30-00"
parts = data.split("-", 3)
print(parts)                # ['2026', '06', '23', '15-30-00']

Exemplo: Analisando um Arquivo de Configuração (Dificuldade ⭐⭐)

PYTHON
# Simula análise de um arquivo de configuração
config_text = """
host=localhost
port=8080
debug=true
theme=dark
"""

# Divide por linha → divide por sinal de igual → armazena em dicionário
config = {}
for line in config_text.strip().split("\n"):
    if "=" in line:
        key, value = line.split("=", 1)
        config[key.strip()] = value.strip()

print(config)
# {'host': 'localhost', 'port': '8080', 'debug': 'true', 'theme': 'dark'}

# Lê configuração
print(f"Host atual: {config.get('host', 'localhost')}")
print(f"Porta atual: {config.get('port', '80')}")
▶ Experimente

Saída:

TEXT
{'host': 'localhost', 'port': '8080', 'debug': 'true', 'theme': 'dark'}
Host atual: localhost
Porta atual: 8080

2. O Poder do join()

join() é o inverso de split() — mescla uma lista em uma string:

PYTHON
# Uso básico
words = ["Hello", "World", "Python"]
sentence = " ".join(words)
print(sentence)             # Hello World Python

# Juntar com vírgulas
csv = ",".join(["Alice", "25", "São Paulo"])
print(csv)                  # Alice,25,São Paulo

# Juntar com novas linhas
lines = "\n".join(["Primeira linha", "Segunda linha", "Terceira linha"])
print(lines)

Vantagens de Desempenho do join()

PYTHON
# ❌ Não recomendado — concatenação de strings em um laço
result = ""
for i in range(1000):
    result += str(i) + ","
# Isso cria 1000 objetos temporários de string (strings são imutáveis)

# ✅ Recomendado — colete em uma lista + join()
parts = [str(i) for i in range(1000)]
result = ",".join(parts)
# Uma mesclagem, muito mais eficiente

Exemplo: Formatando uma Tabela (Dificuldade ⭐⭐)

PYTHON
# Use join + list comprehension para saída de tabela formatada
headers = ["Nome", "Idade", "Cidade"]
rows = [
    ["Alice", "25", "São Paulo"],
    ["Bob", "30", "Rio de Janeiro"],
    ["Charlie", "22", "Belo Horizonte"],
]

# Cabeçalho
print(" | ".join(headers))
print("-" * 25)

# Linhas de dados
for row in rows:
    print(" | ".join(row))
▶ Experimente

Saída:

TEXT
Nome | Idade | Cidade
─────────────────────────
Alice | 25 | São Paulo
Bob | 30 | Rio de Janeiro
Charlie | 22 | Belo Horizonte

3. sorted() com Strings e Dicionários

sorted() funciona em qualquer iterável, não apenas listas:

PYTHON
# Ordenar uma string — ordem alfabética
text = "python"
sorted_chars = sorted(text)
print(sorted_chars)                 # ['h', 'n', 'o', 'p', 't', 'y']
print("".join(sorted_chars))        # hnopty — recombinado

# Ordenar um dicionário — ordena chaves por padrão
d = {"banana": 3, "maçã": 5, "cereja": 2}
sorted_keys = sorted(d)
print(sorted_keys)                  # ['banana', 'cereja', 'maçã']

# Ordenar por valor
sorted_by_value = sorted(d.items(), key=lambda x: x[1])
print(sorted_by_value)              # [('cereja', 2), ('banana', 3), ('maçã', 5)]

# Ordenar um conjunto
s = {3, 1, 4, 1, 5, 9}
sorted_set = sorted(s)
print(sorted_set)                   # [1, 3, 4, 5, 9]

Exemplo: Regra de Ordenação Personalizada (Dificuldade ⭐⭐)

PYTHON
# Ordenar nomes de arquivo pela parte numérica
files = ["file_10.txt", "file_2.txt", "file_1.txt", "file_20.txt"]

# Ordenação regular — ordenação de string, "10" vem antes de "2" (porque '1' < '2')
print(sorted(files))
# ['file_1.txt', 'file_10.txt', 'file_2.txt', 'file_20.txt']

# Ordenar pela parte numérica — extrai número, converte para int, depois ordena
def extract_number(filename):
    num_str = filename.split("_")[1].split(".")[0]
    return int(num_str)

sorted_files = sorted(files, key=extract_number)
print(sorted_files)
# ['file_1.txt', 'file_2.txt', 'file_10.txt', 'file_20.txt']
▶ Experimente

4. enumerate() e zip()

Estas duas funções embutidas são extremamente comuns no trabalho diário.

enumerate() — Obter Índice Durante a Iteração

PYTHON
fruits = ["maçã", "banana", "laranja"]

# Sem enumerate — deselegante
for i in range(len(fruits)):
    print(f"{i + 1}. {fruits[i]}")

# Com enumerate — elegante
for i, fruit in enumerate(fruits, 1):    # start=1 para contagem a partir de 1
    print(f"{i}. {fruit}")

zip() — Iteração Paralela sobre Múltiplas Listas

PYTHON
names = ["Alice", "Bob", "Charlie"]
scores = [85, 92, 78]
cities = ["São Paulo", "Rio de Janeiro", "Belo Horizonte"]

# Iterar sobre três listas simultaneamente
for name, score, city in zip(names, scores, cities):
    print(f"{name}: {score} pontos, de {city}")

Saída:

TEXT
Alice: 85 pontos, de São Paulo
Bob: 92 pontos, de Rio de Janeiro
Charlie: 78 pontos, de Belo Horizonte

Exemplo: Boletim de Notas do Aluno (Dificuldade ⭐⭐⭐)

PYTHON
# Gera um boletim completo usando enumerate + zip
students = ["Alice", "Bob", "Charlie", "Diana"]
portuguese = [85, 92, 78, 88]
math = [90, 85, 95, 80]
english = [78, 95, 82, 90]

print("=== Boletim de Notas ===")
print(f"{'Rank':<4}{'Nome':<8}{'Português':<10}{'Matemática':<10}{'Inglês':<8}{'Média':<8}")

# Calcula médias
averages = [(p + m + e) / 3 for p, m, e in zip(portuguese, math, english)]

# Ordenar por média decrescente
data = list(zip(students, portuguese, math, english, averages))
data.sort(key=lambda x: x[4], reverse=True)

# Exibe
for rank, (name, p, m, e, avg) in enumerate(data, 1):
    print(f"{rank:<4}{name:<8}{p:<10}{m:<10}{e:<8}{avg:<8.1f}")
▶ Experimente

5. Caso Abrangente de Processamento de Dados

Vamos aplicar tudo o que aprendemos a um cenário do mundo real:

Caso: Análise de Log (Dificuldade ⭐⭐⭐)

PYTHON
# Log de servidor simulado
log_data = """
2026-06-20 10:23:45 INFO  Usuário 1001 fez login
2026-06-20 10:25:12 ERRO  Timeout de conexão com banco de dados
2026-06-20 10:26:30 INFO  Usuário 1002 fez login
2026-06-20 10:27:45 WARN  Uso de disco 85%
2026-06-20 10:28:10 ERRO  Usuário 1001 request timeout
2026-06-20 10:29:00 INFO  Usuário 1001 fez logout
"""

# 1. Dividir por linhas
lines = log_data.strip().split("\n")

# 2. Analisar cada entrada de log
parsed = []
for line in lines:
    parts = line.split()
    timestamp = f"{parts[0]} {parts[1]}"
    level = parts[2]
    message = " ".join(parts[3:])
    parsed.append({"time": timestamp, "level": level, "msg": message})

# 3. Contar por nível
level_count = {}
for entry in parsed:
    level = entry["level"]
    level_count[level] = level_count.get(level, 0) + 1

# 4. Exibir ordenado por nível
print("=== Estatísticas de Log ===")
for level, count in sorted(level_count.items()):
    print(f"{level}: {count} entradas")

# 5. Filtrar todos os ERROs
print("\n=== Detalhes de Erros ===")
errors = [e for e in parsed if e["level"] == "ERRO"]
for e in errors:
    print(f"[{e['time']}] {e['msg']}")

Saída:

TEXT
=== Estatísticas de Log ===
ERRO: 2 entradas
INFO: 3 entradas
WARN: 1 entrada

=== Detalhes de Erros ===
[2026-06-20 10:25:12] Timeout de conexão com banco de dados
[2026-06-20 10:28:10] Usuário 1001 request timeout

Casos de Uso Comuns


❓ Perguntas Frequentes

P: Qual a diferença entre split() e split(" ")? R: split() sem argumentos divide por qualquer espaço em branco (espaços, novas linhas, tabulações) e remove automaticamente strings vazias. split(" ") divide apenas por espaços simples; espaços consecutivos produzem strings vazias. Na maioria dos casos, split() sem argumentos é a melhor escolha. ⚠️ P: join() requer que todos os elementos da lista sejam strings? R: Sim. ",".join([1, 2, 3]) dará erro. Converta números para strings primeiro: ",".join(str(x) for x in [1, 2, 3]) ou use str() em uma list comprehension. P: O que acontece quando zip() processa listas de comprimentos diferentes? R: zip() para na lista mais curta. Se uma de três listas tem apenas 2 elementos, zip() produz apenas 2 pares. Para preencher com None até a lista mais longa, use itertools.zip_longest().


📖 Resumo


📝 Atividades

  1. Básico (Dificuldade ⭐): Dado s = "maçã,banana,laranja,uva", use split() para quebrar em uma lista, depois use join() para exibir "maçã | banana | laranja | uva".

  2. Intermediário (Dificuldade ⭐⭐): Dadas duas listas students = ["Alice", "Bob", "Charlie"] e scores = [85, 92, 78], use zip() e enumerate() para exibir um relatório classificado:

    TEXT
    #1: Bob — 92 pontos
    #2: Alice — 85 pontos
    #3: Charlie — 78 pontos
    
  3. Desafio (Dificuldade ⭐⭐⭐): Escreva um "Gerador CSV Simples." Dada uma lista de listas data = [["Nome", "Idade", "Cidade"], ["Alice", 25, "São Paulo"], ["Bob", 30, "Rio de Janeiro"]], exiba como uma string CSV (linhas separadas por vírgula). Dica: Use str() em list comprehension para números, ",".join() para cada linha, "\n".join() para todas as linhas.

100%