Strings en Python: métodos, f-strings y formateo de cadenas

📅 Actualizado en marzo 2026 📊 Nivel: Principiante ⏱️ 18 min de lectura
" str "
The Analytical Engine weaves algebraical patterns
«El motor analítico teje patrones algebraicos»
Ada Lovelace · Primera programadora · 1815 – 1852
Ada Lovelace comprendió antes que nadie que una máquina de cálculo podía manipular símbolos —no solo números—, y que la clave estaba en cómo se representaban y transformaban esas secuencias de caracteres. Un siglo y medio después, str en Python es esa misma intuición hecha realidad: una cadena inmutable de puntos Unicode que puedes dividir, transformar, buscar y reconstruir con una precisión que Ada habría reconocido como pura álgebra.

Los strings (str) son el tipo de dato más ubicuo en Python: mensajes de usuario, ficheros de texto, respuestas de API, URLs, consultas SQL… todo pasa por ellos. Python incluye más de cuarenta métodos de cadena integrados y el sistema de f-strings más expresivo de cualquier lenguaje moderno. Esta lección cubre desde slicing hasta formateo avanzado con especificadores de formato.

🔡 Crear y acceder: índices y slicing

# Tres formas de crear strings
simple    = 'Hola mundo'
doble     = "Hola mundo"          # equivalentes en Python
multiline = """Línea 1
Línea 2
Línea 3"""

# Los strings son secuencias: acceso por índice
s = "Python"
s[0]      # 'P'   — primer carácter
s[-1]     # 'n'   — último carácter
s[-2]     # 'o'   — penúltimo
len(s)    # 6

# Slicing: s[inicio:fin:paso]  (fin es excluido)
s[0:3]    # 'Pyt'   — caracteres 0, 1, 2
s[2:]     # 'thon'  — desde el índice 2 hasta el final
s[:4]     # 'Pyth'  — desde el inicio hasta el 3
s[-3:]    # 'hon'   — últimos 3 caracteres
s[::-1]   # 'nohtyP' — invertir el string ✅

# Slicing con paso
s[::2]    # 'Pto'   — cada 2 caracteres
s[1::2]   # 'yhn'   — desde índice 1, cada 2

# Los strings son INMUTABLES — no se pueden modificar in-place
s[0] = 'p'         # TypeError: 'str' object does not support item assignment
s = 'p' + s[1:]    # ✅ crear uno nuevo: 'python'

# Concatenación y repetición
"Hola" + " " + "mundo"   # 'Hola mundo'
"Ha" * 3                  # 'HaHaHa'
"-" * 40                  # '----------------------------------------'

# Pertenencia
"Py" in "Python"          # True
"Java" not in "Python"    # True
Teclado mecánico retroiluminado con código Python visible en pantalla de monitor al fondo
Los strings son la interfaz entre el código y el mundo real: teclado → str → procesamiento → str → pantalla. Dominar sus métodos es fundamental para cualquier aplicación Python. Fuente: Pexels (licencia libre).

🔍 Búsqueda: find, index, count, in

texto = "La programación en Python es elegante y poderosa"

# find() → devuelve el índice de la primera aparición, -1 si no existe
texto.find("Python")       # 19
texto.find("Java")         # -1
texto.find("a")            # 1  ← primera 'a'
texto.find("a", 5)         # 9  ← primera 'a' a partir del índice 5
texto.find("a", 5, 20)     # 9  ← entre índices 5 y 20

# index() → igual que find() pero lanza ValueError si no encuentra
texto.index("Python")      # 19
texto.index("Java")        # ValueError: substring not found

# rfind() y rindex() — buscan desde el final
texto.rfind("a")           # 47  ← última 'a'

# count() — cuántas veces aparece
texto.count("a")           # 5
texto.count("en")          # 2
texto.count("xx")          # 0

# Operador in (recomendado para comprobar existencia)
"Python" in texto          # True  — más legible que find() != -1
"Java" in texto            # False

# startswith() y endswith()
texto.startswith("La")     # True
texto.startswith("la")     # False  ← sensible a mayúsculas
texto.endswith("osa")      # True

# Tupla de prefijos/sufijos posibles
texto.startswith(("La", "El", "Los"))   # True — coincide con "La"
nombre = "imagen.jpg"
nombre.endswith((".jpg", ".jpeg", ".png", ".webp"))  # True ✅
💡 find() vs index() vs in: Usa in para comprobar existencia (más legible). Usa find() cuando necesites la posición y la ausencia es un caso válido. Usa index() solo cuando el elemento debe existir y quieres que el programa falle ruidosamente si no es así.

🔧 Transformar: upper, lower, strip, replace

s = "  ¡Hola, Mundo!  "

# Mayúsculas y minúsculas
s.upper()           # '  ¡HOLA, MUNDO!  '
s.lower()           # '  ¡hola, mundo!  '
s.capitalize()      # '  ¡hola, mundo!  ' ← solo primera letra del string
s.title()           # '  ¡Hola, Mundo!  ' ← primera letra de cada palabra
s.swapcase()        # '  ¡hOLA, mUNDO!  '

# Eliminar espacios (y otros caracteres)
s.strip()           # '¡Hola, Mundo!'   — quita espacios inicio y fin
s.lstrip()          # '¡Hola, Mundo!  ' — solo inicio
s.rstrip()          # '  ¡Hola, Mundo!' — solo fin
"...hola...".strip(".")      # 'hola' — quita el carácter indicado
"xxhola".lstrip("x")         # 'hola'

# Sustituir
texto = "Me gusta Java. Java es potente."
texto.replace("Java", "Python")          # 'Me gusta Python. Python es potente.'
texto.replace("Java", "Python", 1)      # 'Me gusta Python. Java es potente.' ← solo 1ª vez

# Eliminar un carácter: replace con string vacío
"hola mundo".replace(" ", "")            # 'holamundo'
"precio: 9,99€".replace("€", "").replace(",", ".")  # 'precio: 9.99'

# center, ljust, rjust — alineación
"Python".center(20)          # '       Python       '
"Python".center(20, "-")     # '-------Python-------'
"Python".ljust(20, ".")      # 'Python..............'
"Python".rjust(20)           # '              Python'

# zfill — rellenar con ceros a la izquierda
"42".zfill(6)                # '000042'
str(7).zfill(3)              # '007'

# expandtabs — sustituir \t por espacios
"col1\tcol2\tcol3".expandtabs(10)   # alinea columnas con tabulaciones de 10

✂️ split() y join(): dividir y reunir

# split() — divide un string en lista
"hola mundo python".split()        # ['hola', 'mundo', 'python']
"hola mundo python".split(" ")     # ['hola', 'mundo', 'python']

# Con separador explícito
"uno,dos,tres".split(",")          # ['uno', 'dos', 'tres']
"a::b::c".split("::")              # ['a', 'b', 'c']
"2026-03-09".split("-")            # ['2026', '03', '09']

# Limitar el número de divisiones
"a b c d e".split(" ", 2)         # ['a', 'b', 'c d e']

# rsplit() — divide desde la derecha
"dir/subdir/archivo.txt".rsplit("/", 1)    # ['dir/subdir', 'archivo.txt']

# splitlines() — divide por saltos de línea
"línea1\nlínea2\nlínea3".splitlines()      # ['línea1', 'línea2', 'línea3']

# partition() — divide en exactamente 3 partes en la primera aparición
"usuario@dominio.com".partition("@")       # ('usuario', '@', 'dominio.com')
"sin-arroba".partition("@")               # ('sin-arroba', '', '')

# join() — une una lista en un string ← el patrón más importante
palabras = ["Python", "es", "genial"]
" ".join(palabras)        # 'Python es genial'
"-".join(palabras)        # 'Python-es-genial'
"".join(palabras)         # 'Pythonesgeni al'
"\n".join(palabras)       # 'Python\nes\ngenial'

# join() es O(n), concatenación en bucle es O(n²) — ¡usar siempre join!
# ❌ Lento (O(n²)):
resultado = ""
for palabra in palabras:
    resultado += palabra + " "

# ✅ Rápido (O(n)):
resultado = " ".join(palabras)

# Patrón completo split → procesar → join
csv_line = "Ana,28,Madrid,Python"
campos = csv_line.split(",")
campos[1] = str(int(campos[1]) + 1)   # incrementar edad
nueva_linea = ",".join(campos)         # 'Ana,29,Madrid,Python'
Infografía de métodos de string Python organizados por categoría: búsqueda, transformación, validación, división y formateo
Los más de cuarenta métodos de str agrupados por función: búsqueda y posición, transformación de mayúsculas, limpieza, sustitución, división y unión, validación y alineación. Infografía: Ciberaula.

✅ Validar: isdigit, isalpha, startswith…

# Métodos is* — devuelven True/False
"12345".isdigit()        # True  — solo dígitos (0-9 y equivalentes Unicode)
"12.5".isdigit()         # False — el punto no es un dígito
"hola".isalpha()         # True  — solo letras
"hola123".isalpha()      # False
"hola123".isalnum()      # True  — letras y dígitos
"   ".isspace()          # True  — solo espacios en blanco
"HOLA".isupper()         # True
"hola".islower()         # True
"Hola Mundo".istitle()   # True  — cada palabra comienza en mayúscula

# Validaciones prácticas
def es_numero_entero(s):
    return s.lstrip("+-").isdigit()   # acepta "+42", "-7"

def es_identificador_valido(s):
    return s.isidentifier()            # True si es nombre de variable válido

"mi_var_1".isidentifier()    # True
"1variable".isidentifier()   # False — no puede empezar por dígito
"mi-var".isidentifier()      # False — guión no permitido

# isprintable() — sin caracteres de control
"hola\x00".isprintable()     # False — carácter nulo
"hola".isprintable()         # True

# isascii() — solo caracteres ASCII (< 128)
"hello".isascii()            # True
"héllo".isascii()            # False — é es Unicode > 127

# Validar extensión de archivo
def es_imagen(nombre_archivo):
    EXTENSIONES = (".jpg", ".jpeg", ".png", ".gif", ".webp", ".svg")
    return nombre_archivo.lower().endswith(EXTENSIONES)

es_imagen("foto.JPG")     # True
es_imagen("datos.csv")    # False

✨ f-strings y formateo avanzado

# f-strings (Python 3.6+) — la forma moderna y recomendada
nombre = "Ana"
edad   = 28
ciudad = "Madrid"

f"Hola, {nombre}!"                        # 'Hola, Ana!'
f"{nombre} tiene {edad} años"             # 'Ana tiene 28 años'
f"{nombre.upper()} vive en {ciudad}"      # 'ANA vive en Madrid'

# Expresiones arbitrarias dentro de {}
f"{2 ** 10}"                              # '1024'
f"{edad * 365} días de vida"             # '10220 días de vida'
f"{'Sí' if edad >= 18 else 'No'} mayor"  # 'Sí mayor'

# Especificadores de formato: {valor:especificador}
pi = 3.14159265358979

f"{pi:.2f}"          # '3.14'   — 2 decimales
f"{pi:.5f}"          # '3.14159'
f"{pi:10.3f}"        # '     3.142' — ancho 10, 3 decimales, alineado derecha
f"{pi:<10.3f}"       # '3.142     ' — alineado izquierda
f"{pi:^10.3f}"       # '  3.142   ' — centrado

# Enteros
n = 1234567
f"{n:,}"             # '1,234,567'  — separador de miles
f"{n:_}"             # '1_234_567'  — separador con guión bajo
f"{n:010d}"          # '0001234567' — rellenar con ceros
f"{n:+d}"            # '+1234567'   — signo explícito
f"{255:b}"           # '11111111'   — binario
f"{255:x}"           # 'ff'         — hexadecimal minúsculas
f"{255:X}"           # 'FF'         — hexadecimal mayúsculas
f"{255:o}"           # '377'        — octal
f"{255:#x}"          # '0xff'       — hex con prefijo

# Porcentajes
ratio = 0.8547
f"{ratio:.1%}"       # '85.5%'
f"{ratio:.0%}"       # '85%'

# Fechas con datetime
from datetime import datetime
ahora = datetime.now()
f"{ahora:%d/%m/%Y}"          # '09/03/2026'
f"{ahora:%H:%M:%S}"          # '14:32:07'
f"{ahora:%A, %d de %B}"      # 'Monday, 09 de March'

# Debug con = (Python 3.8+) — imprime nombre y valor
x = 42
f"{x = }"            # 'x = 42'  ← muy útil para depurar
f"{pi = :.3f}"       # 'pi = 3.142'

# Alineación con fill y align
f"{'Python':*^20}"   # '*******Python*******'
f"{'izq':<10}"       # 'izq       '
f"{'der':>10}"       # '       der'

# Cadenas de formato reutilizables con format()
plantilla = "Hola, {}. Tienes {} mensajes."
plantilla.format("Ana", 5)               # 'Hola, Ana. Tienes 5 mensajes.'
plantilla.format("Luis", 0)             # 'Hola, Luis. Tienes 0 mensajes.'

# Con posiciones y nombres
"{0} y {1}, o {1} y {0}".format("A", "B")    # 'A y B, o B y A'
"{nombre} tiene {edad} años".format(nombre="Ana", edad=28)
Pantalla de ordenador mostrando código Python con f-strings y expresiones de formateo en un editor oscuro
Las f-strings de Python 3.6+ son más rápidas que format() y mucho más legibles que la concatenación. Soportan expresiones arbitrarias, especificadores de formato y desde Python 3.8, el operador = para depuración. Fuente: Pexels (licencia libre).

📜 Cadenas multilínea y raw strings

# Strings multilínea con triple comilla
sql = """
    SELECT nombre, email, ciudad
    FROM usuarios
    WHERE activo = 1
      AND ciudad = 'Madrid'
    ORDER BY nombre
"""

html = """

{titulo}

{descripcion}

""".format(titulo="Python", descripcion="El lenguaje más versátil") # Concatenación implícita de literales adyacentes (sin operador) mensaje = ("Esta es una cadena muy larga que " "se divide en varias líneas " "sin usar backslash ni multilínea.") # Backslash para continuar en la siguiente línea mensaje2 = "Esta es una cadena muy larga que " \ "continúa aquí." # Raw strings r"..." — las barras invertidas no se interpretan ruta_win = r"C:\Users\Ana\Desktop\proyecto" # tal cual regex = r"\d{4}-\d{2}-\d{2}" # más legible que "\\d{4}-\\d{2}-\\d{2}" # Comparación: string normal vs raw string print("\n") # imprime un salto de línea print(r"\n") # imprime la barra y la n literalmente: \n # Bytes vs strings texto = "hola" # str (Unicode) bytes_ = b"hola" # bytes (ASCII/bytes crudos) # Conversión texto.encode("utf-8") # b'hola' b"hola".decode("utf-8") # 'hola' "héllo".encode("utf-8") # b'h\xc3\xa9llo' "héllo".encode("latin-1") # b'h\xe9llo'

🌍 Unicode, encode y decode

import unicodedata

# Python 3 usa Unicode (UTF-32 internamente) para todos los strings
"España"          # str normal — 'España' es perfectamente válido
len("España")     # 6 — cuenta puntos de código, no bytes
len("España".encode("utf-8"))   # 7 — 'ñ' ocupa 2 bytes en UTF-8

# Información de un carácter
ord("A")                    # 65  — punto de código Unicode
chr(65)                     # 'A' — carácter desde su código
ord("ñ")                    # 241
ord("🐍")                   # 128013

# unicodedata — información y normalización
unicodedata.name("ñ")       # 'LATIN SMALL LETTER N WITH TILDE'
unicodedata.category("A")   # 'Lu' — Letter, uppercase
unicodedata.category("1")   # 'Nd' — Number, decimal digit

# Normalización — importante para comparaciones
# NFD: descompone "ñ" en "n" + combinador de tilde (2 code points)
# NFC: recompone en un único code point
unicodedata.normalize("NFD", "España")  # 'España' (internamente diferente)
unicodedata.normalize("NFC", "España")  # 'España' (recompuesta)

# Eliminar acentos (útil para slugs y búsqueda)
def quitar_acentos(texto):
    nfd = unicodedata.normalize("NFD", texto)
    return "".join(c for c in nfd if unicodedata.category(c) != "Mn")

quitar_acentos("Programación en España")  # 'Programacion en Espana'

# Crear slugs para URLs
def crear_slug(texto):
    sin_acentos = quitar_acentos(texto.lower())
    return "".join(c if c.isalnum() else "-" for c in sin_acentos).strip("-")

crear_slug("Introducción a Python 3")   # 'introduccion-a-python-3'

# Encode y decode
"hola".encode("utf-8")           # b'hola'
"hola".encode("ascii")           # b'hola'
"España".encode("utf-8")         # b'Espa\xc3\xb1a'
"España".encode("latin-1")       # b'Espa\xf1a'

# Decodificar bytes
b"Espa\xc3\xb1a".decode("utf-8")    # 'España'
b"Espa\xf1a".decode("latin-1")      # 'España'

# Manejo de errores en encode/decode
"España".encode("ascii", errors="ignore")    # b'Espaa' — ignora no-ASCII
"España".encode("ascii", errors="replace")   # b'Espa?a' — sustituye con ?
"España".encode("ascii", errors="xmlcharrefreplace")  # b'España'
Ficha de referencia de f-strings en Python: sintaxis, especificadores de formato para floats, enteros, porcentajes, fechas y alineación
Guía de referencia de f-strings y especificadores de formato. De izquierda a derecha: sintaxis básica, especificadores de ancho y precisión para números, formatos especiales (binario, hexadecimal, porcentaje), formateo de fechas y operador de depuración =. Infografía: Ciberaula.

🛠️ Programa completo: analizador de texto

"""
Analizador de texto — aplica métodos de string para extraer estadísticas,
limpiar contenido y generar un informe formateado de un párrafo de texto.
"""

import unicodedata
import re
from collections import Counter


# ── 1. LIMPIEZA ──────────────────────────────────────────────────────────────

def limpiar_texto(texto):
    """Normaliza espacios, elimina caracteres de control y recorta."""
    # Normalizar saltos de línea
    texto = texto.replace("\r\n", "\n").replace("\r", "\n")
    # Eliminar caracteres de control (excepto \n y \t)
    texto = "".join(c for c in texto if c >= " " or c in "\n\t")
    # Colapsar espacios múltiples en uno
    lineas = [" ".join(linea.split()) for linea in texto.splitlines()]
    return "\n".join(lineas).strip()


# ── 2. ESTADÍSTICAS ──────────────────────────────────────────────────────────

def analizar(texto):
    """Devuelve un dict con estadísticas completas del texto."""
    texto_limpio = limpiar_texto(texto)

    # Caracteres
    total_chars     = len(texto_limpio)
    sin_espacios    = len(texto_limpio.replace(" ", ""))
    letras          = sum(1 for c in texto_limpio if c.isalpha())
    digitos         = sum(1 for c in texto_limpio if c.isdigit())

    # Líneas
    lineas = texto_limpio.splitlines()

    # Palabras
    palabras = texto_limpio.split()
    total_palabras  = len(palabras)
    palabras_lower  = [p.lower().strip(".,;:!?\"'()[]") for p in palabras]
    palabras_unicas = len(set(palabras_lower))
    riqueza_lexica  = palabras_unicas / total_palabras if total_palabras else 0

    # Frases (separadas por . ? !)
    frases = [f.strip() for f in re.split(r"[.!?]+", texto_limpio) if f.strip()]
    longitud_media_frase = (
        sum(len(f.split()) for f in frases) / len(frases) if frases else 0
    )

    # Palabras más frecuentes (excluyendo stopwords básicas)
    STOPWORDS = {"el", "la", "los", "las", "un", "una", "y", "o", "de",
                 "del", "en", "a", "que", "es", "se", "no", "con", "por"}
    palabras_contenido = [p for p in palabras_lower if p not in STOPWORDS and len(p) > 2]
    top_palabras = Counter(palabras_contenido).most_common(5)

    return {
        "texto_limpio":           texto_limpio,
        "total_chars":            total_chars,
        "chars_sin_espacios":     sin_espacios,
        "letras":                 letras,
        "digitos":                digitos,
        "total_lineas":           len(lineas),
        "total_palabras":         total_palabras,
        "palabras_unicas":        palabras_unicas,
        "riqueza_lexica":         riqueza_lexica,
        "total_frases":           len(frases),
        "longitud_media_frase":   longitud_media_frase,
        "top_palabras":           top_palabras,
    }


# ── 3. INFORME ────────────────────────────────────────────────────────────────

def imprimir_informe(stats):
    """Formatea y muestra el informe con f-strings y especificadores."""
    sep = "═" * 52

    print(f"\n  {sep}")
    print(f"  {'ANÁLISIS DE TEXTO':^52}")
    print(f"  {sep}")

    print(f"\n  {'Caracteres':.<30} {stats['total_chars']:>10,}")
    print(f"  {'Sin espacios':.<30} {stats['chars_sin_espacios']:>10,}")
    print(f"  {'Letras':.<30} {stats['letras']:>10,}")
    print(f"  {'Dígitos':.<30} {stats['digitos']:>10,}")
    print(f"  {'Líneas':.<30} {stats['total_lineas']:>10,}")

    print(f"\n  {'Palabras totales':.<30} {stats['total_palabras']:>10,}")
    print(f"  {'Palabras únicas':.<30} {stats['palabras_unicas']:>10,}")
    print(f"  {'Riqueza léxica':.<30} {stats['riqueza_lexica']:>10.1%}")
    print(f"  {'Frases':.<30} {stats['total_frases']:>10,}")
    print(f"  {'Palabras por frase (media)':.<30} {stats['longitud_media_frase']:>10.1f}")

    print(f"\n  {'TOP 5 PALABRAS':}")
    print(f"  {'-'*30}")
    for i, (palabra, freq) in enumerate(stats["top_palabras"], 1):
        barra = "█" * freq
        print(f"  {i}. {palabra:<18} {freq:3}  {barra}")

    print(f"\n  {sep}\n")


# ── 4. EJECUCIÓN ─────────────────────────────────────────────────────────────

TEXTO_EJEMPLO = """
Python es un lenguaje de programación de alto nivel, interpretado y de propósito general.
Python fue creado por Guido van Rossum y publicado por primera vez en 1991.
Python enfatiza la legibilidad del código y permite a los programadores expresar
conceptos en menos líneas de código que en C++ o Java.
Python es actualmente el lenguaje más popular del mundo según múltiples índices.
Python soporta múltiples paradigmas: programación orientada a objetos, programación
funcional y programación imperativa. Python cuenta con una comunidad enorme y un
ecosistema de bibliotecas que cubre desde ciencia de datos hasta desarrollo web.
"""

stats = analizar(TEXTO_EJEMPLO)
imprimir_informe(stats)

# Modo interactivo
print("  Pega tu texto (escribe FIN en una línea vacía para terminar):")
print("  " + "─" * 40)
lineas_usuario = []
while True:
    linea = input("  ")
    if linea.strip().upper() == "FIN":
        break
    lineas_usuario.append(linea)

if lineas_usuario:
    texto_usuario = "\n".join(lineas_usuario)
    stats_usuario = analizar(texto_usuario)
    imprimir_informe(stats_usuario)
else:
    print("  No se introdujo texto.")

🐛 Errores clásicos con strings

1. Concatenar string y número directamente

edad = 28
"Tengo " + edad + " años"        # TypeError: can only concatenate str (not "int")
"Tengo " + str(edad) + " años"   # ✅ convertir a string
f"Tengo {edad} años"             # ✅ mejor: usar f-string

2. Esperar que replace() modifique el string in-place

s = "hola mundo"
s.replace("hola", "adiós")   # no hace nada útil — el resultado se descarta
print(s)                      # sigue siendo 'hola mundo' ← bug silencioso

s = s.replace("hola", "adiós")   # ✅ asignar el resultado
print(s)                           # 'adiós mundo'

3. Comparar strings con == ignorando mayúsculas o espacios

entrada = input("¿Continuar? (s/n): ")
if entrada == "s":            # falla si el usuario escribe "S" o " s"
    ...

# ✅ Normalizar antes de comparar
if entrada.strip().lower() == "s":
    ...

4. Construir strings con + en un bucle (O(n²))

palabras = ["uno", "dos", "tres", "cuatro", "cinco"]

# ❌ Lento para listas grandes
resultado = ""
for p in palabras:
    resultado += p + ", "

# ✅ Rápido: join
resultado = ", ".join(palabras)

5. Olvidar que split() sin argumento y split(" ") son diferentes

"  hola   mundo  ".split()       # ['hola', 'mundo']    ✅ limpio
"  hola   mundo  ".split(" ")    # ['', '', 'hola', '', '', 'mundo', '', ''] ← ojo

6. IndexError al acceder a un string vacío

s = ""
s[0]              # IndexError: string index out of range

# ✅ Comprobar antes
if s:
    primera = s[0]
# O con valor por defecto:
primera = s[0] if s else ""

✅ Resumen y próximos pasos

Los strings en Python combinan inmutabilidad, Unicode nativo y un arsenal de métodos que cubren prácticamente cualquier operación de texto: búsqueda, transformación, validación, división y formateo. Las f-strings hacen que el formateo sea tan natural como escribir la expresión directamente, con especificadores de formato que evitan conversiones manuales.

Con esta lección se completa el Módulo 3 — Estructuras de datos: listas, tuplas, diccionarios, conjuntos y ahora strings. El siguiente módulo, Funciones y módulos, comienza con def, parámetros y return, los bloques con los que encapsularás toda la lógica que acabas de aprender a manejar.

❓ Preguntas frecuentes

❓ Preguntas frecuentes sobre Strings en Python: métodos, f-strings y formateo de cadenas

Las dudas más comunes respondidas de forma clara y directa.

La inmutabilidad tiene tres ventajas clave. Primera, seguridad: si una función recibe un string, sabes que no puede modificar el original, lo que evita efectos secundarios inesperados. Segunda, hashabilidad: como los strings no cambian, Python puede calcular su hash una sola vez y usarlos como claves de diccionario o elementos de set. Tercera, interning: Python puede reutilizar el mismo objeto en memoria para strings idénticos (especialmente strings cortos), ahorrando espacio. En cuanto al rendimiento, sí, si construyes un string con concatenación en un bucle (s = s + x repetido N veces) obtienes O(n²). La solución idiomática es join(): "".join(lista), que es O(n). Para manipulaciones muy intensivas existe io.StringIO o bytearray.
La respuesta casi siempre es f-strings (Python 3.6+): son las más legibles, las más rápidas en benchmarks y soportan expresiones arbitrarias dentro de las llaves. Usa format() cuando necesites separar la plantilla de los datos (internacionalización, plantillas almacenadas como strings). Usa % solo para compatibilidad con código antiguo o cuando formateas mensajes de logging (el módulo logging usa % por razones de rendimiento: si el log level está desactivado, no evalúa los argumentos). En código nuevo, f-strings son la elección por defecto.
La diferencia es sutil pero importante. split() sin argumento divide por cualquier espacio en blanco (espacios, tabulaciones, saltos de línea) y elimina los campos vacíos, incluyendo los del inicio y el final. " hola mundo ".split() devuelve ["hola", "mundo"]. split(" ") divide estrictamente por el carácter espacio, conservando los campos vacíos entre espacios múltiples y devolviendo strings vacíos al principio y al final si los hay. " hola mundo ".split(" ") devuelve ["", "", "hola", "", "", "mundo", "", ""]. Para parsear texto libre, split() sin argumento es casi siempre lo que quieres.
La forma más robusta es usar unicodedata.normalize con la forma NFD (descomposición canónica), que separa cada letra acentuada en su letra base más el acento como carácter combinatorio separado, y después filtrar los caracteres cuya categoría Unicode sea "Mn" (Mark, Nonspacing). import unicodedata; unicodedata.normalize("NFD", texto).encode("ascii", "ignore").decode("ascii"). Si solo necesitas slugs para URLs, una alternativa popular es la librería python-slugify.
Usa raw strings cuando el contenido incluya muchas barras invertidas que no quieres que Python interprete como secuencias de escape. Los dos casos más frecuentes son: expresiones regulares (re.compile(r"\d+\.\d+") vs re.compile("\\d+\\.\\d+"): el raw string es mucho más legible) y rutas de Windows (r"C:\Users\Ana\Desktop" vs "C:\\Users\\Ana\\Desktop"). En rutas, la alternativa moderna es usar pathlib.Path que maneja separadores automáticamente en cualquier SO.
Valora este artículo

💬 Foro de discusión

¿Tienes dudas sobre Strings en Python: métodos, f-strings y formateo de cadenas? Comparte tu pregunta con la comunidad.

¿Tienes cuenta? o comenta como invitado ↓

Todavía no hay mensajes. ¡Sé el primero en participar!