trubidata
Lección 6 de 12·20 min

Strings a fondo

En esta guía (14)

Ya venís usando strings desde la primera lección. En esta vas a verlos como lo que son, una secuencia de caracteres, y vas a conocer los métodos que resuelven el 90% del trabajo con texto: cambiar mayúsculas, limpiar espacios, buscar y reemplazar, partir un texto en pedazos y volver a unirlo, y formatear salidas prolijas.

Un string es una secuencia

Todo lo que aprendiste de índices y slicing en listas funciona con strings:

python
palabra = "Python"
print(palabra[0])     # P
print(palabra[-1])    # n
print(palabra[1:4])   # yth
print(palabra[::-1])  # nohtyP
print(len(palabra))   # 6
print("th" in palabra)  # True

Con strings, in busca subtextos, no solo caracteres sueltos.

Los strings son inmutables

A diferencia de una lista, no podés cambiar un carácter de un string:

text
>>> palabra = "Python"
>>> palabra[0] = "J"
TypeError: 'str' object does not support item assignment

Todas las operaciones que "modifican" un string en realidad devuelven uno nuevo. Si querés conservar el cambio, tenés que asignarlo:

python
nombre = "ana"
nombre.upper()          # devuelve "ANA", pero nadie lo guarda
print(nombre)           # ana
nombre = nombre.upper() # ahora sí
print(nombre)           # ANA

Esto es lo más importante de la lección: los métodos de string nunca cambian el original.

Mayúsculas y minúsculas

python
texto = "hola MUNDO, qué tal"
print(texto.upper())       # HOLA MUNDO, QUÉ TAL
print(texto.lower())       # hola mundo, qué tal
print(texto.title())       # Hola Mundo, Qué Tal
print(texto.capitalize())  # Hola mundo, qué tal

Un uso muy común: comparar sin que importen las mayúsculas.

python
respuesta = "SI"
if respuesta.lower() == "si":
    print("Confirmado")
text
Confirmado

Limpiar espacios

Cuando el texto viene del usuario o de un archivo, suele traer espacios de más:

python
sucio = "   Mendoza  \n"
print(f"[{sucio.strip()}]")    # [Mendoza]
print(f"[{sucio.lstrip()}]")   # quita solo a la izquierda
print(f"[{sucio.rstrip()}]")   # quita solo a la derecha
text
[Mendoza]
[Mendoza  
]
[   Mendoza]

strip() saca espacios, tabs y saltos de línea de los extremos (no del medio). También le podés pasar qué caracteres sacar: "--hola--".strip("-") da "hola".

Acostumbrate a hacer input(...).strip(): el usuario puede tipear un espacio sin darse cuenta.

Buscar y reemplazar

python
frase = "el gato y el perro y el loro"

print(frase.count("el"))           # 3
print(frase.find("perro"))         # 13 (posición donde empieza)
print(frase.find("vaca"))          # -1 (no está)
print(frase.startswith("el"))      # True
print(frase.endswith(".txt"))      # False
print(frase.replace("el", "un"))   # un gato y un perro y un loro
print(frase.replace("el", "un", 1))  # un gato y el perro y el loro

replace reemplaza todas las apariciones, salvo que le pases cuántas como tercer argumento. Sirve, por ejemplo, para aceptar coma decimal:

python
texto = "12,5"
numero = float(texto.replace(",", "."))
print(numero * 2)  # 25.0

Preguntar qué tiene un texto

Estos métodos devuelven True o False:

python
print("2026".isdigit())     # True: solo dígitos
print("abc".isalpha())      # True: solo letras
print("abc123".isalnum())   # True: letras y/o dígitos
print("   ".isspace())      # True: solo espacios
print("Hola".isupper())     # False
print("hola".islower())     # True

Ojo: "".isdigit() es False (un texto vacío no tiene dígitos), y "-5".isdigit() también es False por el signo.

split y join: partir y unir

split parte un string y devuelve una lista:

python
linea = "Ana,28,Córdoba"
partes = linea.split(",")
print(partes)  # ['Ana', '28', 'Córdoba']

nombre, edad, ciudad = partes
print(f"{nombre} tiene {int(edad)} años")  # Ana tiene 28 años

frase = "  muchas   palabras   sueltas "
print(frase.split())  # ['muchas', 'palabras', 'sueltas']

Sin argumentos, split() corta por cualquier cantidad de espacios y descarta los vacíos. Con un separador, corta exactamente ahí.

join hace lo inverso: une una lista de strings usando un separador. Se escribe al revés de lo que uno espera, el separador primero:

python
palabras = ["hola", "que", "tal"]
print(" ".join(palabras))    # hola que tal
print("-".join(palabras))    # hola-que-tal
print("".join(palabras))     # holaquetal

join solo acepta strings. Si tenés números, convertilos primero: ", ".join(str(n) for n in [1, 2, 3]) da "1, 2, 3". (Esa expresión dentro de los paréntesis es como una list comprehension sin corchetes; para join funciona igual.)

Con splitlines() partís un texto de varias líneas en una lista de líneas:

python
texto = "primera\nsegunda\ntercera"
print(texto.splitlines())  # ['primera', 'segunda', 'tercera']

Caracteres especiales y strings de varias líneas

Dentro de un string, la barra invertida \ arma secuencias de escape:

SecuenciaSignifica
\nsalto de línea
\ttabulación
\\una barra invertida
\"comilla doble dentro de un string con comillas dobles
python
print("Nombre:\tAna\nEdad:\t28")
text
Nombre:	Ana
Edad:	28

Para textos largos, las triples comillas permiten escribir varias líneas tal cual:

python
mensaje = """Hola,
este mensaje tiene
varias líneas."""
print(mensaje)
text
Hola,
este mensaje tiene
varias líneas.

Si querés que las barras invertidas no se interpreten (útil en rutas de Windows), anteponé una r: r"C:\nueva\carpeta" se guarda literalmente.

Formato a fondo

En la lección 2 viste lo básico de las f-strings. Estos son los formatos que más se usan para armar salidas prolijas:

python
producto = "Café"
precio = 4500.5
stock = 7

print(f"|{producto:<10}|")    # alineado a la izquierda en 10 lugares
print(f"|{producto:>10}|")    # a la derecha
print(f"|{producto:^10}|")    # centrado
print(f"|{producto:*^10}|")   # centrado, rellenando con *
print(f"|{stock:03d}|")       # entero con ceros a la izquierda
print(f"|{precio:>10.2f}|")   # 10 lugares, 2 decimales, a la derecha
print(f"|{precio:,.2f}|")     # separador de miles
text
|Café      |
|      Café|
|   Café   |
|***Café***|
|007|
|   4500.50|
|4,500.50|

El formato general es {valor:relleno alineación ancho .decimales tipo}, y todas las partes son opcionales. Con eso podés armar tablas:

python
productos = [("Yerba", 3200, 12), ("Azúcar", 1100.5, 0), ("Café molido", 4500, 7)]

print(f"{'Producto':<12}{'Precio':>10}{'Stock':>7}")
print("-" * 29)
for nombre, precio, stock in productos:
    print(f"{nombre:<12}{precio:>10.2f}{stock:>7}")
text
Producto        Precio  Stock
-----------------------------
Yerba          3200.00     12
Azúcar         1100.50      0
Café molido    4500.00      7

Un truco para depurar: f"{variable=}" muestra el nombre y el valor.

python
total = 1250
print(f"{total=}")  # total=1250

Limpieza de texto: un ejemplo completo

Juntando todo: tenés nombres cargados a mano, con espacios y mayúsculas desprolijas, y querés normalizarlos.

python
crudos = ["  ana PÉREZ", "bruno  gómez ", "CARLA díaz", "  ", "diego  ruiz"]

limpios = []
for nombre in crudos:
    nombre = " ".join(nombre.split())   # colapsa espacios repetidos y recorta
    if nombre:                          # descarta los que quedaron vacíos
        limpios.append(nombre.title())

print(limpios)
text
['Ana Pérez', 'Bruno Gómez', 'Carla Díaz', 'Diego Ruiz']

" ".join(texto.split()) es un truco muy usado: split() separa por cualquier cantidad de espacios y join vuelve a unir con uno solo.

Errores comunes

  • Llamar a un método y no guardar el resultado. texto.strip() solo no cambia texto. Hacé texto = texto.strip().
  • Intentar cambiar un carácter con texto[0] = .... Los strings son inmutables: armá uno nuevo, por ejemplo "J" + texto[1:].
  • Usar join al revés. Es separador.join(lista), no lista.join(separador).
  • Pasarle números a join. Da TypeError: sequence item 0: expected str instance, int found. Convertí cada elemento con str().
  • Comparar textos sin normalizar. "Si" == "si" es False. Usá .strip().lower() en los dos lados.
  • Confiar en isdigit() para decimales o negativos. "3.5".isdigit() y "-2".isdigit() dan False.

Practicá

  1. Pedí una frase y decí si es un palíndromo (se lee igual al derecho y al revés), sin importar mayúsculas ni espacios. Por ejemplo, "Anita lava la tina" lo es.
  2. Tenés el texto de configuración "host=localhost;puerto=8080;modo=prueba". Convertilo en el diccionario {'host': 'localhost', 'puerto': '8080', 'modo': 'prueba'}.
  3. Escribí un programa que pida un nombre de usuario y lo valide: entre 4 y 12 caracteres, solo letras y números, y que no empiece con un número. Mostrá un mensaje distinto para cada problema.
  4. Dada la lista items = [("Notebook", 1, 850000), ("Mouse", 2, 12500.5), ("Monitor", 1, 210000)] (producto, cantidad, precio unitario), imprimí un ticket alineado con el subtotal de cada línea y el total al final, con separador de miles y dos decimales.

Soluciones

Ejercicio 1:

python
frase = input("Frase: ")
normalizada = "".join(frase.lower().split())
if normalizada == normalizada[::-1]:
    print("Es palíndromo")
else:
    print("No es palíndromo")
text
Frase: Anita lava la tina
Es palíndromo

Ejercicio 2:

python
texto = "host=localhost;puerto=8080;modo=prueba"
config = {}
for par in texto.split(";"):
    clave, valor = par.split("=")
    config[clave] = valor
print(config)  # {'host': 'localhost', 'puerto': '8080', 'modo': 'prueba'}

Ejercicio 3:

python
usuario = input("Usuario: ").strip()

if not 4 <= len(usuario) <= 12:
    print("Tiene que tener entre 4 y 12 caracteres")
elif not usuario.isalnum():
    print("Solo puede tener letras y números")
elif usuario[0].isdigit():
    print("No puede empezar con un número")
else:
    print(f"Usuario '{usuario}' válido")
text
Usuario: 9lives
No puede empezar con un número

Como las condiciones van en orden, cuando llegás a usuario[0] ya sabés que el texto tiene al menos 4 caracteres, así que el índice 0 existe.

Ejercicio 4:

python
items = [("Notebook", 1, 850000), ("Mouse", 2, 12500.5), ("Monitor", 1, 210000)]

total = 0
for producto, cantidad, precio in items:
    subtotal = cantidad * precio
    total += subtotal
    print(f"{producto:<10}{cantidad:>3} x {precio:>12,.2f}{subtotal:>15,.2f}")
print("-" * 43)
print(f"{'TOTAL':<28}{total:>15,.2f}")
text
Notebook    1 x   850,000.00     850,000.00
Mouse       2 x    12,500.50      25,001.00
Monitor     1 x   210,000.00     210,000.00
-------------------------------------------
TOTAL                          1,085,001.00

Resumen

  • Un string es una secuencia: índices, slicing, len e in funcionan como en las listas.
  • Los strings son inmutables: los métodos devuelven un string nuevo y hay que guardarlo.
  • upper, lower, title cambian mayúsculas; strip limpia los extremos; replace reemplaza; find y count buscan.
  • isdigit, isalpha, isalnum validan contenido.
  • split parte un texto en una lista; separador.join(lista) une una lista de strings.
  • \n y \t son salto de línea y tabulación; las triples comillas permiten texto de varias líneas.
  • En las f-strings, :<10, :>10, :^10, :.2f y :, controlan alineación, decimales y separador de miles.

← Volver al temario