Ir al contenido
wannacode

Cadenas: trabajar con texto

En resumen: Una cadena (string) es texto, una secuencia de caracteres con índices desde 0: tiene una longitud y métodos para buscar, reemplazar, recortar, dividir en partes y comparar.

Problema

El código es correcto, pero no funciona

La tienda da un 10% de descuento con el código VERANO10. Una clienta lo copia del anuncio, pero lo escribe en minúsculas y sin querer pone un espacio delante:

code = input()
if code == "VERANO10":
print("10% de descuento")
else:
print("Código no válido")
Entrada
verano10
Salida
Código no válido

Para una persona, el código es el mismo. Para el programa, verano10 y VERANO10 son textos distintos: el primero tiene un carácter más, y las letras son otras. Tienes que poder mirar dentro de un texto y arreglarlo.

La idea

El texto es una secuencia de caracteres

El texto son caracteres colocados uno detrás de otro: letras, cifras, espacios, signos. Cada carácter tiene un índice, como en un array. El primero tiene el índice 0.

code = "VERANO10"
print(len(code))
print(code[0])
print(code[len(code) - 1])
Salida
8
V
0
  • len(code) es el número de caracteres.
  • code[0] es el carácter con índice 0. El último carácter tiene el índice len(code) - 1.

Aquí no hay un tipo aparte para un solo carácter (en Java y C# se llama char). Un carácter es un texto de longitud 1. Las comillas simples y las dobles hacen lo mismo: 'V' y "V" son el mismo texto.

code = "VERANO10"
print(code[-1])
print(type(code[0]))
print(len(code[0]))
print('V' == "V")
Salida
0
<class 'str'>
1
True

code[-1] es el último carácter: un índice negativo cuenta desde el final, -1 es el último, -2 el penúltimo. Es más corto que code[len(code) - 1].

len da la longitud tanto del texto como de la lista.

Míralo

Carácter a carácter

¿Cuántas cifras tiene el número de teléfono? Recorres los índices desde 0 hasta el último y miras cada carácter:

phone = "0888 123 456"
digits = 0
for i in range(len(phone)):
c = phone[i]
if c >= "0" and c <= "9":
digits += 1
print(f"Cifras: {digits}")
Salida
Cifras: 10

c >= "0" and c <= "9" funciona porque cada carácter tiene un código: un número en la tabla de caracteres. Los textos se comparan por los códigos de sus caracteres. Las cifras de "0" a "9" tienen códigos seguidos, y también las letras de "a" a "z".

Más precisamente, para curiosos
  • Para comprobaciones así hay métodos ya hechos: c.isdigit(), c.isalpha(), c.isupper(), c.islower(). También conocen letras que no están en el alfabeto inglés, como é o ñ.
  • ord("A") da el código de un carácter, es decir, 65. Al revés, chr(66) es "B". Un texto y un número no se suman: "a" + 1 detiene el programa con TypeError.
  • Sin índice: for c in phone: recorre directamente los caracteres del texto.
print("7".isdigit(), "é".isalpha(), "É".isupper(), "é".islower())
print(ord("A"), chr(66))
try:
print("a" + 1)
except TypeError as e:
print(f"TypeError: {e}")
digits = 0
for c in "0888 123 456":
if c.isdigit():
digits += 1
print(digits)
Salida
True True True True
65 B
TypeError: can only concatenate str (not "int") to str
10

Pruébalo

¿Qué carácter?

¿Qué imprimirá el programa?

word = "Factura"
print(word[3])
print(len(word))
Respuesta

La idea

Los métodos del texto

El texto trae métodos ya hechos: acciones que llamas con un punto después del texto. Este es el arreglo del código promocional:

code = " verano10"
clean = code.strip().upper()
print(f"[{clean}]")
print(clean == "VERANO10")
Salida
[VERANO10]
True

strip() quita los espacios del principio y del final. upper() pone todas las letras en mayúscula. Los métodos se pueden encadenar uno tras otro: el primero devuelve un texto, y el segundo se llama sobre él.

Algunos más, sobre una dirección de correo:

email = "lucia.garcia@correo.es"
print("@" in email)
print(email.find("@"))
print(email[0:email.find("@")])
print(email.replace(".", " "))
print(email.endswith(".es"))
Salida
True
12
lucia.garcia
lucia garcia@correo es
True
Método Qué hace
x in email si x está dentro
find(x) el índice donde aparece x por primera vez (-1 si no está)
email[a:b] una parte del texto
replace(x, y) cada x se reemplaza por y
startswith(x), endswith(x) si empieza (termina) por x
lower() todas las letras en minúscula

"@" in email no es un método, sino un operador: in pregunta si el texto de la izquierda aparece en el texto de la derecha. Una parte del texto se toma con corchetes y dos puntos, email[a:b]; hay más sobre eso en «Más precisamente» abajo.

print("lucia.garcia@correo.es".find("#"))
print("Casa".startswith("C"))
print("Casa".lower())
Salida
-1
True
casa
Más precisamente, para curiosos

date[a:b] toma los caracteres desde el índice a hasta el índice b, sin b. Son b - a caracteres. Sin final, date[a:], toma todo hasta el final. Un índice negativo cuenta desde el final: date[-2:] son los dos últimos caracteres.

date = "2026-10-24"
print(date[5:7])
print(date[8:])
print(date[-2:])
Salida
10
24
24

La idea

El texto no cambia

Hay una particularidad que al principio confunde a todo el mundo:

name = "maria"
name.upper()
print(name)
name = name.upper()
print(name)
Salida
maria
MARIA

La segunda línea no hace nada visible. upper() no cambia name. Crea un texto nuevo en mayúsculas y lo devuelve. Nadie lo guarda, y se pierde.

Una vez creado, un texto no se puede cambiar. Se dice que es inmutable (immutable). Cada método que «cambia» un texto en realidad devuelve uno nuevo. Para guardarlo, lo asignas: name = name.upper().

name = "maria"
name.upper()
print(name)
name = name.upper()
print(name)
Paso a paso, en palabras
  1. name guarda el texto «maria»: 5 caracteres con índices del 0 al 4.
  2. upper() no toca «maria». Crea un texto nuevo, «MARIA».
  3. Nadie guarda el texto nuevo, y se pierde.
  4. name sigue guardando «maria», y eso es lo que se imprime.
  5. Otro texto nuevo, «MARIA», pero ahora = lo guarda en name. El antiguo «maria» se descarta.
  6. Ahora name guarda «MARIA».
Más precisamente, para curiosos
  • Tampoco puedes cambiar un carácter dentro de un texto con un índice: name[0] = "M" detiene el programa con TypeError: 'str' object does not support item assignment. Creas un texto nuevo, por ejemplo "M" + name[1:].
  • Cuando tienes muchos trozos, júntalos en una lista y únelos todos de una vez con join:
parts = ["leche", "pan", "huevos"]
print(", ".join(parts))
Salida
leche, pan, huevos

Pruébalo

Encuentra el error

La usuaria escribe su correo con mayúsculas y espacios. El programa debería limpiarlo y dejarla entrar, pero dice «No existe ese usuario.». ¿En qué línea está el error?

Elige la línea con el error.

La idea

El texto en partes

A menudo un texto guarda varias cosas separadas por un signo: productos con una coma, palabras con un espacio. split lo divide en partes y devuelve una lista de textos:

shopping = "leche,pan,huevos,queso"
items = shopping.split(",")
print(f"Productos: {len(items)}")
for i in range(len(items)):
print(f"{i + 1}. {items[i]}")
Salida
Productos: 4
1. leche
2. pan
3. huevos
4. queso

El separador no forma parte de los trozos. A partir de aquí trabajas con una lista normal: longitud, índices, un bucle.

Así también se lee una línea entera de números desde el teclado: la divides y conviertes cada parte en un número. Es justo lo que te faltaba en la lección anterior, la de las tablas:

parts = input().split(" ")
total = 0
for p in parts:
total += int(p)
print(total)
Entrada
42 38 51 47 60
Salida
238
Más precisamente, para curiosos
  • Dos espacios seguidos dan una parte vacía '' entre ellos. split() sin argumento divide por cualquier espacio en blanco y no da partes vacías; además se salta los espacios del principio y del final.
  • Lo contrario de split es ", ".join(items): une las partes con un separador.
print("a b".split(" "))
print(" a b ".split())
print(", ".join(["a", "b"]))
Salida
['a', '', 'b']
['a', 'b']
a, b

Pruébalo

¿Es lo mismo?

En Python, == compara el contenido de los textos, letra por letra. Pero una letra mayúscula y una minúscula son caracteres distintos. La entrada es Madrid:

¿Qué imprimirá el programa?

city = input()
print(city == "Madrid")
print(city == "madrid")
print(city.lower() == "madrid")
Respuesta
Más precisamente, para curiosos

También existe el operador is. No compara las letras: pregunta si los dos lados son un mismo objeto en memoria. El texto leído del teclado es un objeto nuevo, así que con la entrada admin obtienes esto:

user = input()
print(user is "admin")
print(user == "admin")
Salida
False
True

Compara siempre el texto con ==.

Ejercicio

Nombres y palabras

Resuelve los ejercicios en tu editor. El texto se lee del teclado como una línea entera.

1. El nombre al revés. Lee un nombre e imprímelo de atrás hacia delante. Recorres los índices desde el último hasta 0 y añades los caracteres a un texto nuevo.

Entrada
Carmen
Salida
nemraC

2. Número de palabras. Lee una frase y cuenta las palabras. Entre las palabras puede haber más de un espacio, y puede haber espacios al principio y al final. Pista: una palabra empieza donde el carácter no es un espacio y el anterior sí lo es (o no hay ninguno antes).

Entrada
Hoy es un día festivo
Salida
Palabras: 5

3. Palíndromo. Un palíndromo se lee igual de delante hacia atrás que de atrás hacia delante. Los espacios y las mayúsculas no cuentan. Quita los espacios, pon las letras en minúscula y compara el primer carácter con el último, el segundo con el penúltimo, y así sucesivamente.

Entrada
Anita lava la tina
Salida
Es un palíndromo
Entrada
Pan con queso
Salida
No es un palíndromo

Ejercicio

Comprobaciones y conteo

4. Contraseña segura. Pide una contraseña hasta que el usuario escriba una segura: al menos 8 caracteres, al menos una cifra, una mayúscula y una minúscula. Después de cada contraseña débil, di qué se pide. Pista: while True con break cuando la contraseña es segura, y una comprobación de cada carácter con isdigit, isupper, islower.

Entrada
cafe
cafe2026
Cafe2026
Salida
Contraseña:
Contraseña débil: al menos 8 caracteres, una cifra, una mayúscula y una minúscula.
Contraseña:
Contraseña débil: al menos 8 caracteres, una cifra, una mayúscula y una minúscula.
Contraseña:
Contraseña aceptada.

Más ejercicios

  • Comas en vez de espacios. Lee una frase y reemplaza cada espacio por una coma. Mañana nos vamos a Valencia → Mañana,nos,vamos,a,Valencia.
  • El nombre más largo. Lee nombres separados por comas e imprime el más largo. Ana,Cristina,Pedro → Cristina.
  • Las vocales con asterisco. Reemplaza cada vocal (a, e, i, o, u) por *, sea mayúscula o minúscula. Me gusta leer → M* g*st* l**r.
  • Frecuencia de las letras. Cuenta cuántas veces aparece cada letra en el texto, sin distinguir mayúsculas y minúsculas. Pista: una lista de 26 contadores, uno para cada letra de 'a' a 'z' (la ñ y las vocales con tilde quedan fuera de ese rango: de momento puedes no contarlas). El índice de la letra c es ord(c) - ord("a"). Imprime solo las letras que aparecen.
  • Gráfico de caracteres. Como el ejercicio anterior, pero en lugar del número imprime esa cantidad de asteriscos: a: ****.
  • Cuántas veces cada palabra. Lee una frase y, para cada palabra distinta, imprime cuántas veces aparece. Pista: divídela en palabras y, para cada palabra, comprueba si ya se contó antes en la lista.
  • Ordenar por longitud. Lee palabras separadas por espacios e imprímelas de la más corta a la más larga. Ordena la lista como ordenabas números, pero compara las longitudes.
  • Número de oraciones. Cuenta las oraciones de un texto: cada una termina con ., ! o ?. Cuidado con ... y ?!: terminan una oración, no tres.
  • Paréntesis equilibrados. Comprueba si los paréntesis de un texto están equilibrados. Con un solo tipo de paréntesis basta un contador: ( suma 1, ) resta 1. El contador nunca debe bajar de 0, y al final debe ser 0. Con tres tipos, (), [], {}, necesitas una lista de caracteres donde guardas los paréntesis abiertos, y un contador de hasta dónde está lleno: en un paréntesis de cierre, el último abierto tiene que ser del mismo tipo. {[()]} está equilibrado, ([)] no.

Test

Ponte a prueba

1. ¿Qué da len("Casa")?
2. ¿Qué hace la línea name.upper() sola, sin asignación?
3. ¿Qué da "Sevilla" == "sevilla" en Python?
4. ¿Qué diferencia hay entre 'a' y "a" en Python?
5. ¿Qué da "lun,mar,vie".split(",")?

Creado por Ivo Gergov como parte de la campaña de Evo Tech por una educación accesible en programación ·