Strings:
índice, fatia e métodos
Quase todo dado que entra no sistema entra como texto — e texto quase nunca chega do jeito que a gente precisa. Hoje o texto vira matéria-prima manipulável.
Quase todo dado que entra no sistema entra como texto — e texto quase nunca chega do jeito que a gente precisa. Hoje o texto vira matéria-prima manipulável.
Acessar caracteres por índice — positivo e negativo — e percorrer uma string com laço
Fatiar strings com [inicio:fim:passo] e explicar por que o fim não entra
Aplicar os métodos essenciais — strip, lower, replace, find, split, join
Reconhecer a imutabilidade e saber que todo método devolve uma nova string
Formulário, arquivo, planilha, API, teclado: a porta de entrada é sempre uma sequência de caracteres. Antes de virar número, data ou registro no banco, alguém precisa ler, limpar e recortar esse texto.
nome digitado: " ana MARIA silva " o que o sistema precisa: "Ana Maria Silva"
Virem e conversem: onde vocês já viram um sistema errar por causa de texto mal tratado? (nome duplicado por causa de espaço, login que não aceita maiúscula, CEP com traço…)
Assim como o vetor da Semana 15, a string tem posições numeradas a partir do zero. A diferença: cada posição guarda um caractere, não um valor qualquer.
linguagem = "PYTHON"
print(linguagem[0]) # P
print(linguagem[3]) # H
print(linguagem[-1]) # N (último)
print(len(linguagem)) # 6
-1 é sempre o último caractere, independentemente do tamanho. É o jeito seguro de pegar o fim sem calcular len() - 1.
linguagem[6] não existe: IndexError. Com 6 caracteres, o último índice válido é 5.
palavra = "AULA"
for letra in palavra:
print(letra)
A U L A
palavra = "AULA"
for i in range(len(palavra)):
print(i, "->", palavra[i])
0 -> A 1 -> U 2 -> L 3 -> A
Você consegue ler qualquer posição, mas não consegue escrever em nenhuma. Uma string, depois de criada, nunca muda: o que a gente faz é criar outra.
nome = "ana"
nome[0] = "A"
TypeError: 'str' object does not support item assignment
nome = "ana"
nome = "A" + nome[1:]
print(nome) # Ana
Ana
texto.upper() não altera texto. Ele devolve uma string nova. Se você não guardar o retorno em algum lugar, o resultado é jogado fora — e o programa segue com o texto velho, sem dar erro nenhum. Erro de lógica clássico (Semana 18).
O fatiamento (slicing) recorta um pedaço da string. Começa no início e para antes do fim — o índice final não entra na fatia.
s = "PYTHON"
s[1:4] # "YTH" (1, 2 e 3)
s[:3] # "PYT" (do começo)
s[3:] # "HON" (até o fim)
s[:] # "PYTHON" (cópia inteira)
s[-3:] # "HON" (últimos três)
fim - início dá exatamente o tamanho da fatia. s[1:4] tem 4-1 = 3 caracteres. E s[:3] + s[3:] reconstrói a string inteira, sem sobrar nem faltar letra.
s[0:99] devolve "PYTHON". Diferente do índice solto, o fatiamento perdoa.
| Expressão | Resultado | Leitura |
|---|---|---|
| s[::1] | "PROGRAMAR" | de um em um — o padrão |
| s[::2] | "PORMR" | de dois em dois, pulando um |
| s[1::2] | "RGAA" | começa em 1 e pula um |
| s[::-1] | "RAMARGORP" | inverte a string inteira |
| s[3:7:2] | "GA" | de 3 a 6, de dois em dois |
def eh_palindromo(texto):
"""Diz se o texto é igual de trás para frente."""
limpo = texto.lower().replace(" ", "")
return limpo == limpo[::-1]
print(eh_palindromo("Arara")) # True
print(eh_palindromo("Ame a ema")) # True
print(eh_palindromo("Python")) # False
[::-1] é a inversão idiomática em Python. Repare que a função combina três ideias do dia: método (lower), método (replace) e fatiamento com passo negativo — em uma linha só.
return e tem docstring. Ou seja: testável. Guarde — vamos testá-la no Dia 2.
Considerando s = "ALGORITMO":
"GORI" — inclui as posições 2, 3, 4 e 5"GOR" — inclui as posições 2, 3 e 4 ✓"LGO" — começa a contar do 1"ALG" — pega os três primeiros0 (A=0, L=1, G=2) e o índice final não entra. Vai de 2 até 4 → "GOR", com 5-2 = 3 caracteres.
a = "bom"
b = "dia"
a + " " + b # "bom dia" (concatenação)
"-" * 20 # "--------------------"
"dia" in "bom dia" # True
"noite" not in "bom dia" # True
len("bom dia") # 7
in em decisãoemail = input("E-mail: ")
if "@" not in email:
print("E-mail inválido")
"idade: " + 15 gera TypeError. É preciso converter: "idade: " + str(15) — ou, melhor, usar f-string (próximo slide).
in é o teste de contém mais barato que existe — devolve True/False direto e serve para qualquer trecho, não só um caractere.
nome = "Ana"
nota = 8.5
msg = "Aluno " + nome + \
" tirou " + str(nota) + \
" no bimestre."
str() e é fácil esquecer um espaço.nome = "Ana"
nota = 8.5
msg = f"Aluno {nome} tirou {nota} no bimestre."
# formatando dentro da chave:
f"Média: {nota:.2f}" # Média: 8.50
f"{nome:>10}" # alinhado à direita
f vem antes das aspas e cada { } é avaliado como expressão — inclusive {nota * 2} ou {nome.upper()}.
" ANA maria SILVA " "ana.maria@Escola.COM.BR " "1.234,50" "11/09/2026"
Nenhum desses valores está pronto para uso. Cortar na mão, caractere por caractere, funcionaria — mas seria reinventar o que a linguagem já traz pronto. Os métodos de string são funções que já vêm acopladas a todo texto.
Pense: quantas linhas você escreveria, usando só laço e índice, para remover os espaços das pontas de um texto? E se existisse um método que faz isso com uma palavra?
| Método | Entrada | Saída |
|---|---|---|
| .upper() | "ana maria" | "ANA MARIA" |
| .lower() | "ANA Maria" | "ana maria" |
| .title() | "ana maria" | "Ana Maria" |
| .capitalize() | "ana maria" | "Ana maria" |
senha_digitada = "AdMiN"
# comparação à prova de caixa
if senha_digitada.lower() == "admin":
print("acesso liberado")
.title() não conhece português: "maria de souza" vira "Maria De Souza". Para nomes formais, ainda é preciso tratar as preposições.
t = " dados "
t.strip() # "dados"
t.lstrip() # "dados "
t.rstrip() # " dados"
"###total###".strip("#") # "total"
cpf = "123.456.789-00"
cpf.replace(".", "").replace("-", "")
# "12345678900"
"1.234,50".replace(".", "").replace(",", ".")
# "1234.50" → pronto para float()
.strip() só limpa as pontas. Espaços do meio continuam lá — "ana maria".strip() continua com três espaços entre os nomes. Para isso serve " ".join(texto.split()), daqui a três slides.
texto.strip().lower().replace(" ", "_"). Lê-se da esquerda para a direita, em ordem de execução.
texto = " python "
texto.strip().upper()
print(texto)
PYTHON — os dois métodos foram aplicados" PYTHON " — só o upper valeu" python " — a variável não mudou ✓"PYTHON", mas o resultado não foi atribuído a ninguém — foi descartado. O certo é texto = texto.strip().upper(). Nenhum erro é lançado: é o erro de lógica silencioso da Semana 18.
| Método | Devolve | Se não achar |
|---|---|---|
| .find("@") | índice da 1ª ocorrência | -1 (não quebra) |
| .index("@") | índice da 1ª ocorrência | ValueError (quebra) |
| .count("a") | quantas vezes aparece | 0 |
| .startswith("R$") | True / False | False |
| .endswith(".com") | True / False | False |
email = "ana@escola.com"
pos = email.find("@")
if pos == -1:
print("sem arroba")
else:
print("usuário:", email[:pos])
print("domínio:", email[pos+1:])
usuário: ana domínio: escola.com
find devolve uma posição; a posição alimenta um fatiamento. É assim que se quebra um texto sem saber de antemão onde ele quebra.
find quando "não achar" é uma possibilidade normal que você vai tratar com if. Use index quando não achar significa que os dados estão corrompidos e o programa deve parar.
frase = "ana maria silva"
frase.split()
# ['ana', 'maria', 'silva']
linha = "Ana;8.5;9.0;7.5"
linha.split(";")
# ['Ana', '8.5', '9.0', '7.5']
"2026-09-11".split("-")
# ['2026', '09', '11']
bagunca = "ana maria silva"
bagunca.split(" ")
# ['ana', '', '', '', 'maria', '', '', 'silva']
bagunca.split()
# ['ana', 'maria', 'silva'] ← ignora repetição
split() quebra por qualquer quantidade de espaço em branco (inclusive tabulação e quebra de linha) e descarta os vazios. É quase sempre o que você quer para texto digitado por gente.
split transforma texto em vetor. A partir daí vale tudo que vocês já sabem: percorrer com for, acessar por índice, usar len.
partes = ['ana', 'maria', 'silva']
" ".join(partes) # "ana maria silva"
"-".join(partes) # "ana-maria-silva"
"".join(partes) # "anamariasilva"
# o combo mais útil do dia:
sujo = " ana MARIA silva "
limpo = " ".join(sujo.split()).title()
print(limpo) # "Ana Maria Silva"
join é o separador, não a lista. Leia como: "cole os itens da lista usando este separador entre eles".
" ".join([1, 2, 3]) dá TypeError. Se a lista tem números, converta antes.
split e join são inversos: um desmonta, o outro remonta. Quase toda limpeza de texto é um split, alguma coisa no meio, e um join.
def normalizar_nome(bruto):
"""
Padroniza um nome digitado por usuário.
Args:
bruto (str): nome como veio do formulário.
Returns:
str: nome sem espaços sobrando e com
cada palavra capitalizada.
"""
partes = bruto.split() # limpa espaços
juntas = " ".join(partes) # remonta com 1 espaço
return juntas.title() # padroniza a caixa
>>> normalizar_nome(" ana MARIA silva ")
'Ana Maria Silva'
>>> normalizar_nome("PEDRO")
'Pedro'
>>> normalizar_nome(" ")
''
A linha do arquivo é linha = "Ana;8.5;9.0;7.5". Você precisa da segunda nota.
linha.split(";")[3]linha.split(";")[2] ✓linha.join(";")[2]linha[2]split(";") produz ['Ana', '8.5', '9.0', '7.5'] — o nome ocupa a posição 0, então a segunda nota está na posição 2. A alternativa D devolve o caractere 'a': linha ainda é texto, e texto se indexa por caractere.
| Preciso… | Uso | Exemplo |
|---|---|---|
| padronizar caixa | .lower() / .upper() / .title() | "ANA".lower() → "ana" |
| tirar espaço das pontas | .strip() | " x ".strip() → "x" |
| remover/trocar trecho | .replace(velho, novo) | "a-b".replace("-","") → "ab" |
| saber se contém | in / .startswith / .endswith | "@" in email → True |
| achar a posição | .find(x) | "a@b".find("@") → 1 |
| contar ocorrências | .count(x) | "banana".count("a") → 3 |
| quebrar em pedaços | .split(sep) | "a,b".split(",") → ['a','b'] |
| juntar pedaços | sep.join(lista) | "-".join(['a','b']) → "a-b" |
| recortar por posição | [início:fim:passo] | "PYTHON"[:3] → "PYT" |
contar_vogais(texto) — devolve quantas vogais existem, ignorando a caixa.
iniciais(nome) — "ana maria silva" → "A.M.S."
mascarar_email(email) — "ana@escola.com" → "a**@escola.com"
so_numeros(texto) — "(11) 98765-4321" → "11987654321"
Args e Returnsprint — todas usam return@ com find, fatie o usuário, e monte a máscara com [0] + "*" * (tamanho - 1).
-1 é o último, len() dá o tamanho[início:fim:passo], o fim não entra, [::-1] invertestrip nas pontas · replace em todo lugar · lower/title na caixain pergunta, find localiza, count contaNo Dia 2, o texto deixa de ser recortado e passa a ser julgado: sanitizar, validar e formatar dados de entrada — com um validador de cadastro que nasce testado.
-1; o inválido é len(s)s[a:b] tem b - a caracteress = s.metodo().strip().lower() nos dois lados antesfind devolve -1 quando não acha; index quebra o programa" ".join(texto.split()) resolve espaço duplicado em qualquer lugars.strip().lower().replace(...)SEDUC-SP. Educação Profissional Paulista — Técnico em Desenvolvimento de Sistemas. Lógica de Programação — Manipulação de strings (Semana 19, aulas 1 e 2). Códigos: SISANO1C1B3S19A1 e A2.
ASCENCIO, A. F. G.; CAMPOS, E. A. V. Fundamentos da programação de computadores. São Paulo: Pearson Education do Brasil, 2012.
FORBELLONE, A. L. V.; EBERSPÄCHER, H. F. Lógica de programação: a construção de algoritmos e estruturas de dados. São Paulo: Pearson, 2005.
MENEZES, N. N. C. Introdução à programação com Python. 3. ed. São Paulo: Novatec, 2019.
PYTHON SOFTWARE FOUNDATION. Built-in Types — Text Sequence Type str. Documentação oficial. Disponível em: docs.python.org. Acesso em: 14 ago. 2026.
Aula compilada (dobradinha) · adaptação para apresentação HTML por Guilherme Antunes