Skip to content
This page has been auto-translated and may contain errors.View in English

Strings ​

El texto aparece en casi todos los programas que escribes. Nombres, mensajes, puntajes, etiquetas. En Python, a cualquier fragmento de texto se le llama string: cualquier valor que envuelvas entre comillas. Simples o dobles, ambas funcionan igual.

Los strings son el tipo de texto principal de Python. Cargan de todo, desde un nombre de usuario hasta una ruta de URL o una salida formateada. Las comillas simples y dobles producen resultados idénticos; la elección es solo de estilo.

str está presente en cada límite del sistema: entrada/salida por terminal, contenido de archivos, respuestas de red, datos serializados. Es el tipo de secuencia Unicode inmutable (no se puede modificar después de creado) de Python. Ambos estilos de comillas producen el mismo objeto, así que la elección entre ellos es puramente de estilo.

python
greeting = "Hello, world"
username = 'alice'

El único momento en que la elección de comillas importa es cuando tu texto contiene comillas. Usa el estilo opuesto para no tener que escaparlas:

La convención de la comunidad son las comillas dobles. La razón práctica para cambiar de estilo es evitar el escape cuando el contenido incluye ese mismo carácter:

La convención son las comillas dobles, y formateadores como Black y Ruff lo aplican automáticamente. La única razón para cambiar manualmente es evitar una barra invertida de escape cuando el contenido incluye el delimitador:

python
note = "It's a great day"      # apóstrofe adentro, usa comillas dobles
message = 'She said "hello"'   # comillas dobles adentro, usa comillas simples
escaped = "She said \"hello\""  # o escápalas con una barra invertida

Inmutabilidad ​

Los strings son inmutables: una vez que creas uno, no puedes cambiarlo. Piensa en un string como algo fijo desde el momento en que se crea. Cualquier operación que parezca modificar un string en realidad está produciendo uno completamente nuevo. El original queda exactamente igual que antes.

Los strings son inmutables: ningún método modifica un string en su lugar. Cada operación que transforma texto devuelve un string nuevo y deja el original intacto. La consecuencia práctica es que una llamada a un método que no asignas a nada no tiene ningún efecto.

Los objetos str son inmutables, es decir, su contenido queda fijo una vez creados y nada puede escribir sobre ellos. Esto le da a los strings dos propiedades que realmente usas: son hashables (un valor cuyo contenido nunca cambia puede clasificarse por ese contenido, que es lo que permite que un string sirva como clave de diccionario o miembro de un set), y es seguro pasarlos entre nombres sin que nadie los copie, porque nadie puede modificar un string compartido por debajo de ti.

python
name = "alice"
name = name.upper()   # "ALICE" es un string nuevo; "alice" no cambia

La consecuencia directa: no puedes cambiar un carácter en una posición específica. Python lanzará un error si lo intentas.

python
name = "alice"
name[0] = "A"   # TypeError: 'str' object does not support item assignment

Para obtener un string modificado, construye uno nuevo usando slicing o un método. Ambos se explican más abajo.

Intentar asignar un carácter muestra la restricción de forma directa:

python
name = "alice"
name[0] = "A"   # TypeError: 'str' object does not support item assignment

Cuando necesitas una versión modificada, las herramientas estándar son slicing combinado con concatenación para ediciones posicionales, y replace() para sustituciones. Ambas producen un string nuevo y dejan el original intacto.

Asignar a una posición (name[0] = "A") siempre lanza TypeError, sin excepción. Para una edición posicional, construye un string nuevo haciendo slicing alrededor de la parte que quieres cambiar: name[:1].upper() + name[1:] capitaliza el primer carácter. Para una sustitución en cualquier parte del string, usa replace().

JunoInmutabilidad Un string nunca cambia una vez que existe. Cualquier cosa que parezca editarlo en realidad te devuelve un string nuevo, así que asigna el resultado o se te escapa. Lo que me confundió al principio: name[0] = "A" no funciona, lanza un TypeError.
JunoInmutabilidad Ningún método de string edita en el lugar, todos devuelven un string nuevo y dejan el original intacto. Así que name.upper() solo no hace nada útil, tienes que asignarlo. Y name[0] = "A" lanza TypeError, no existe un intercambio de carácter en el lugar.
JunoInmutabilidad La inmutabilidad es lo que hace que los strings sean hashables, así que funcionan como claves de dict, y seguros de compartir sin copiar. Consecuencia práctica: asigna el resultado de cada método transformador, porque ninguno toca el original. Para una edición posicional, haz slicing alrededor del punto y reconstruye, porque la asignación por índice siempre lanza TypeError.

Indexación y slicing ​

Cada carácter de un string tiene una posición numerada, empezando desde cero. Puedes leer caracteres individuales poniendo ese número de posición entre corchetes. Los números negativos cuentan hacia atrás desde el final.

Los strings son secuencias con indexación desde cero. Los índices negativos cuentan desde el final. El slicing extrae cualquier rango contiguo en una sola expresión, y nunca lanza un error con valores fuera de rango.

Un string se comporta como una secuencia ordenada que puedes indexar y recortar con slicing. Leer una sola posición (s[i]) lanza IndexError si el índice apunta más allá del final. El slicing (s[start:stop:step]) se comporta distinto: los límites fuera de rango se ajustan silenciosamente a lo que existe, así que un slice nunca puede lanzar IndexError. Esa diferencia es la que hay que recordar en la práctica: el acceso por índice es estricto, el slicing es permisivo.

python
word = "Python"
#       012345

print(word[0])    # "P"
print(word[2])    # "t"
print(word[5])    # "n"
print(word[-1])   # "n"  (último carácter)
print(word[-2])   # "o"  (penúltimo carácter)

-1 siempre es el último carácter, -2 el penúltimo, y así sucesivamente. Son útiles cuando quieres el final de un string sin saber su longitud exacta.

Los índices negativos se traducen así: -1 es len(s) - 1, -2 es len(s) - 2. Son más útiles para acceder desde el final cuando no quieres calcular la longitud manualmente. Un índice negativo que queda fuera de rango también lanza IndexError, igual que uno positivo.

Un índice negativo se convierte en len(s) + i antes de la verificación de límites, así que -1 cae en el último carácter y -2 en el anterior. Salirse de rango lanza IndexError en ambos casos, sea positivo o negativo: solo el slicing es permisivo con eso, la indexación simple no lo es.

El slicing extrae un fragmento. [start:stop] incluye start y excluye stop:

python
word = "Python"

print(word[0:2])   # "Py"     (posiciones 0 y 1)
print(word[2:])    # "thon"   (posición 2 hasta el final)
print(word[:3])    # "Pyt"    (desde el inicio hasta la posición 2)
print(word[:])     # "Python" (una copia de todo el string)
print(word[::2])   # "Pto"    (cada segundo carácter)
print(word[::-1])  # "nohtyP" (invertido)

Tres patrones son los que más vas a usar: word[:n] para los primeros n caracteres, word[n:] para todo desde la posición n en adelante, word[-n:] para los últimos n caracteres. word[::-1] invierte un string. Se ve raro la primera vez, pero es idiomático en Python y lo verás seguido.

A diferencia de la indexación directa, el slicing nunca lanza IndexError. Python ajusta silenciosamente los índices fuera de rango, así que word[100:] en un string corto devuelve "" en vez de fallar. El argumento step controla el paso: word[::2] toma cada dos caracteres, word[::-1] recorre en reversa.

En s[start:stop:step], cualquier parte que omitas toma por defecto "el extremo natural según la dirección en que vas", no un 0 y un len() fijos. Con un step positivo eso significa de inicio a fin; con un step negativo se invierte, así que start se convierte en el último carácter y stop se sale por el frente. Por eso s[::-1] recorre todo el string en reversa sin que escribas ningún límite, y por la misma razón s[::-2] te da cada segundo carácter al revés.

JunoIndexación y slicing Las posiciones empiezan en cero, así que word[0] es el primer carácter y word[-1] es el último. Un slice toma un rango: word[start:stop] conserva start y se detiene justo antes de stop. word[::-1] invierte el string, lo cual se ve raro la primera vez y después lo usas para siempre.
JunoIndexación y slicing Indexa desde cero, o desde el final con negativos, donde word[-1] es el último carácter. Los slices toman un rango que incluye start y excluye stop, y un tercer valor step define el paso, así que word[::-1] invierte. El detalle que vale la pena recordar: indexar más allá del final lanza IndexError, pero el slicing más allá del final devuelve lo que hay en vez de fallar.
JunoIndexación y slicing La indexación simple es estricta y lanza IndexError fuera de rango, el slicing es permisivo y se ajusta a lo que exista, así que word[100:] devuelve "" en vez de lanzar un error. Omite una parte del slice y toma por defecto el extremo natural según la dirección del step, que es justo la razón por la que word[::-1] invierte sin ningún límite escrito. Recurre a un slice cuando prefieras no fallar ante una entrada vacía o corta.

Métodos esenciales de strings ​

Los strings vienen con un conjunto de métodos incorporados: operaciones que llamas directamente sobre cualquier valor de tipo string. Escribes el string (o la variable que lo contiene), luego un punto, y luego el nombre del método. Cada método devuelve un string nuevo. El original nunca cambia.

Los métodos de strings son funciones asociadas al tipo str. Como los strings son inmutables, cada método devuelve un string nuevo en vez de modificar el original. Una llamada a un método que no asignas ni pasas a ningún lado no tiene efecto duradero.

Cada método transformador devuelve un str nuevo y deja el original intacto, lo cual se deriva directamente de la inmutabilidad. También operan sobre code points (los caracteres en sí, no los bytes crudos usados para almacenarlos), así que los métodos funcionan correctamente con texto acentuado y no latino sin que hagas nada especial. La contrapartida a tener en cuenta: cada método reserva memoria para un string nuevo, así que encadenar muchos sobre texto grande implica muchas asignaciones de memoria.

Mayúsculas y minúsculas ​

python
text = "Hello, World"

text.lower()       # "hello, world"
text.upper()       # "HELLO, WORLD"
text.title()       # "Hello, World"  (cada palabra capitalizada)
text.capitalize()  # "Hello, world"  (solo la primera palabra)

lower() y upper() son los dos que más vas a usar. lower() es particularmente útil al comparar texto: "Alice" y "alice" se vuelven lo mismo una vez que llamas .lower() en ambos lados.

lower() es el paso estándar de normalización antes de comparar o almacenar. title() capitaliza la primera letra de cada palabra usando una regla aproximada que falla con contracciones: "it's" se convierte en "It'S". Trátalo como formateo solo para mostrar en pantalla.

lower() aplica la conversión completa de mayúsculas/minúsculas de Unicode. Para una comparación sin distinguir mayúsculas, casefold() es más correcto: aplica transformaciones adicionales (por ejemplo, la ß alemana se convierte en ss) que lower() omite. title() capitaliza después de cualquier carácter no alfanumérico, lo cual maneja mal las contracciones y los nombres con guion. Para una capitalización de título correcta, implementa la lógica manualmente.

Espacios en blanco ​

python
text = "  hello  "

text.strip()    # "hello"    (ambos lados)
text.lstrip()   # "hello  "  (solo a la izquierda)
text.rstrip()   # "  hello"  (solo a la derecha)

strip() elimina los espacios de ambos extremos de un string. Lo vas a usar casi siempre que manejes entradas del usuario o texto de un archivo, porque los espacios sueltos causan fallas silenciosas: "alice" != "alice ".

strip() elimina todos los espacios en blanco al inicio y al final: espacios, tabulaciones y saltos de línea. Las variantes direccionales te permiten limpiar solo un lado, útil para quitar un salto de línea final sin tocar la indentación. Las tres aceptan un argumento opcional de caracteres para eliminar caracteres específicos en su lugar.

Sin argumento, strip() elimina todo tipo de espacio en blanco de ambos extremos, incluyendo el que no es ASCII, no solo el espacio simple. Con un argumento de caracteres, elimina cualquiera de esos caracteres de los extremos, y ahí está la trampa: el argumento es un conjunto de caracteres a eliminar, no un prefijo a buscar. "xxhelloxx".strip("x") devuelve "hello", pero "https://".strip("https") no elimina el prefijo "https", sino que elimina cada h, t, p y s de ambos extremos y devuelve "://". Para eliminar un prefijo o sufijo conocido, usa removeprefix() y removesuffix() en su lugar.

Búsqueda ​

python
text = "Hello, world"

text.find("world")         # 7
text.find("Python")        # -1  (no encontrado)
text.count("l")            # 3
text.startswith("Hello")   # True
text.endswith("world")     # True

find() devuelve la posición donde empieza un fragmento de texto dentro de tu string. Si no está ahí, devuelve -1. Usa startswith() y endswith() cuando solo te importa si el string empieza o termina con algo específico.

find() devuelve el índice de inicio de la primera coincidencia, o -1. La convención del -1 te permite usar el resultado directamente en slicing o aritmética sin necesitar una verificación. startswith() y endswith() aceptan cada una una tupla de strings, así puedes probar varios prefijos o sufijos en una sola llamada.

find() recorre de izquierda a derecha y devuelve -1 cuando no hay coincidencia. index() hace la misma búsqueda pero lanza ValueError en vez de devolver -1: elige index() cuando una coincidencia faltante significa que tu código tiene un bug y quieres que se detenga ahí, y find() cuando la ausencia es una entrada normal que vas a verificar. Para una pregunta pura de "empieza o termina con esto", startswith() y endswith() expresan justo lo que quieres decir y se detienen ante la primera discrepancia, así que son preferibles a un find() o a un in para esa tarea.

Reemplazo ​

python
text = "Hello, world"

text.replace("world", "Python")   # "Hello, Python"
text.replace("l", "L")            # "HeLLo, worLd"  (todas las ocurrencias)
text.replace("l", "L", 1)         # "HeLlo, world"  (solo la primera)

replace() intercambia cada ocurrencia de un fragmento de texto por otro y te devuelve un string nuevo. El original no cambia. Pasa un tercer argumento si solo quieres reemplazar la primera ocurrencia.

replace() reemplaza todas las ocurrencias no superpuestas por defecto. El argumento count limita cuántas se reemplazan. Como devuelve un string nuevo, las llamadas se pueden encadenar: text.replace("a", "A").replace("e", "E") aplica ambas sustituciones en secuencia.

replace() busca una subcadena literal, no un patrón, así que no hace nada de regex y trata cada carácter del argumento tal como es. Reemplaza coincidencias no superpuestas de izquierda a derecha, lo cual puede sorprenderte: "aaa".replace("aa", "b") da "ba", no "bb", porque la segunda aa se superpone con la primera coincidencia. El argumento count limita cuántas reemplaza, y como cada llamada devuelve un string nuevo, puedes encadenarlas: text.replace(",", "").replace(" ", "_").

División y unión ​

split() corta un string en pedazos según un separador y te los devuelve como una lista. Tú le dices en qué cortar:

split() divide según un separador y devuelve los segmentos como una lista. Llamado sin argumento, divide en cualquier secuencia de espacios en blanco y descarta strings vacíos que surgen de espacios consecutivos:

split(sep) recorre de izquierda a derecha, dividiendo en cada ocurrencia no superpuesta de sep. Sin argumento usa un algoritmo distinto: divide en cualquier secuencia de espacios en blanco y elimina los espacios al inicio y al final del resultado. rsplit(sep, n) divide desde la derecha, útil para aislar el último segmento de una ruta con puntos o un identificador con namespace.

python
csv_row = "Ana,28,Ciudad de México"
parts = csv_row.split(",")     # ["Ana", "28", "Ciudad de México"]

"  hello   world  ".split()   # ["hello", "world"]

split() devuelve una lista, una secuencia ordenada de valores. Tienen su propio capítulo, Lists; por ahora, trátalas como la secuencia de partes que split() produce y join() consume.

join() hace lo contrario: combina una lista de strings en uno solo. El string antes de .join() se coloca entre cada elemento:

python
words = ["Hello", "world"]

" ".join(words)    # "Hello world"
", ".join(words)   # "Hello, world"
"".join(words)     # "Helloworld"

El patrón para recordar: separador.join(lista_de_strings). El separador va a la izquierda, la lista a la derecha. " ".join(words) pone un espacio entre cada palabra. "".join(words) las pega sin nada en medio.

join() es la herramienta indicada cuando estás armando un solo string a partir de varias piezas. Realiza una sola asignación de memoria en vez de crear un string nuevo en cada paso. Para dos o tres strings, + está perfectamente bien. Una vez que tienes una lista de tamaño considerable, recurre a join().

join() recorre las piezas una vez, calcula el tamaño total, reserva la memoria del resultado una sola vez, y escribe todo. Construir el mismo string con + repetido en un bucle es la forma costosa de hacerlo: como los strings no pueden cambiar, cada + reserva un string nuevo y copia todo lo acumulado hasta ese momento, así que el costo crece con el cuadrado del número de piezas. Con un puñado de strings nadie lo nota, pero con unos miles convierte una operación rápida en lenta. La regla que evita esto: junta las piezas en una lista y usa join() una sola vez al final, nunca uses += con un string dentro de un bucle.

JunoMétodos esenciales de strings Cada uno de estos devuelve un string nuevo, así que asigna el resultado o se pierde. Los que vas a usar a diario: .lower() y .upper() para cambiar mayúsculas y minúsculas, .strip() para quitar espacios sueltos, .find() para ubicar texto (devuelve -1 cuando no está), .replace() para intercambiar texto, y .split() junto con sep.join() para separar un string y volver a armarlo.
JunoMétodos esenciales de strings Todos estos devuelven un string nuevo, ninguno muta, así que encadénalos o asígnalos. Ten claras las trampas: .strip("x") toma un conjunto de caracteres a eliminar, no un prefijo, y .split() sin argumento colapsa secuencias de espacios en blanco. Para armar muchas piezas, construye una lista y aplícale sep.join().
JunoMétodos esenciales de strings Las dos trampas que muerden en código real: .strip(chars) elimina un conjunto de caracteres de los extremos, no un prefijo, así que usa removeprefix() cuando te refieras a un prefijo, y construir un string con += en un bucle es la forma lenta, así que junta en una lista y haz join() una sola vez. Para comparar, normaliza con .casefold() en vez de .lower(), y trata .title() como algo solo para mostrar en pantalla, ya que arruina las contracciones.

f-strings ​

Los f-strings incrustan valores directamente dentro del texto. Pon f antes de la comilla de apertura, y luego envuelve cualquier variable o expresión en llaves. Python lo completa cuando el código se ejecuta. También puedes agregar dos puntos después del valor para controlar cómo se muestra.

Los f-strings evalúan cualquier expresión dentro de {} en tiempo de ejecución y convierten el resultado a string. Los dos puntos dentro de las llaves introducen un format spec: una sintaxis compacta para controlar decimales, alineación y formato de números.

Cada {} en un f-string termina llamando al propio método __format__ del valor (un dunder, el método de doble guion bajo que Python invoca por detrás al formatear un valor), pasándole lo que hayas escrito después de los dos puntos. Así que cualquier clase que escribas puede decidir cómo aparece dentro de un f-string definiendo __format__. Las flags de conversión !r, !s y !a ejecutan primero repr(), str() o ascii() sobre el valor; !r es la que conviene recordar, porque muestra un valor tal como lo escribirías en código, comillas y escapes incluidos, algo que se ve en la práctica a continuación.

python
name = "Ana"
score = 94.5

print(f"Hello, {name}!")           # "Hello, Ana!"
print(f"Score: {score:.1f}%")      # "Score: 94.5%"
print(f"2 + 2 = {2 + 2}")          # "2 + 2 = 4"
print(f"Name: {name.upper()}")     # "Name: ANA"

El format spec después de : controla cómo se muestra el valor:

SpecSignificadoEjemplo
.2f2 decimalesf"{3.14159:.2f}" → "3.14"
.0%porcentaje, sin decimalesf"{0.94:.0%}" → "94%"
,separador de milesf"{1000000:,}" → "1,000,000"
>10alinea a la derecha en 10 caracteresf"{'hi':>10}" → " hi"

.2f es el que más vas a usar: cada vez que muestres un decimal y quieras un número prolijo en vez de una fila larga de dígitos. Todo lo demás en la tabla está ahí para cuando lo necesites. Puedes poner cualquier variable, operación aritmética o llamada a un método dentro de las {}.

.2f y .0% cubren la mayoría del formateo para mostrar en pantalla. Los especificadores de alineación (>, <, ^) producen salida tabular cuando se combinan con un ancho. El patrón general es {value:[align][width][.precision][type]}. Una vez que reconoces las piezas, cualquier spec se puede leer sin memorizar todas las combinaciones.

El mismo spec puede significar cosas distintas según el tipo, porque cada tipo se formatea a sí mismo: f"{'hi':5}" rellena el texto por la derecha mientras que f"{42:5}" rellena un número por la izquierda, mismo :5, resultado opuesto. La flag de conversión que vale la pena convertir en costumbre es !r: ejecuta repr() antes de formatear, lo cual envuelve strings en comillas y convierte caracteres invisibles (tabulaciones, espacios al final, saltos de línea) en secuencias de escape visibles. Cuando una salida se ve sutilmente rara, cambiar {value} por {value!r} es la forma más rápida de ver qué hay realmente ahí.

Junof-strings Pon f antes de la comilla de apertura, envuelve cualquier variable, suma o llamada a un método en {}, y Python coloca el resultado ahí cuando la línea se ejecuta. Los dos puntos dentro de las llaves controlan el aspecto: :.2f para dos decimales es el que más vas a usar. Mucho más prolijo que pegar texto con +.
Junof-stringsf"..." evalúa cualquier expresión dentro de {} y coloca el resultado directamente, sin necesitar str(). Después de los dos puntos viene el format spec: :.2f, :,, :>10 y compañía, todos siguiendo {value:[align][width][.precision][type]}. Aprende las piezas una vez y puedes leer cualquier spec sin memorizarlas.
Junof-strings Cada {} llama al propio __format__ del valor, así que el spec después de los dos puntos significa lo que ese tipo decida, por eso :5 rellena texto y números en direcciones opuestas. La flag que conviene mantener es !r: muestra un valor tal como lo escribirías, así que los espacios sueltos y otras cosas invisibles saltan a la vista en el momento en que la salida se ve rara.

Strings de varias líneas ​

Para escribir un string que abarque más de una línea, usa comillas triples: tres " al inicio y tres al final. Python conserva todos los saltos de línea y espacios exactamente como los escribiste.

Los strings entre comillas triples conservan todos los espacios en blanco y saltos de línea de forma literal. Son estándar para bloques de texto largos, como plantillas de correo o consultas SQL, y para docstrings: la documentación en línea colocada al inicio del cuerpo de una función o clase.

Un string entre comillas triples conserva cada carácter exactamente, incluyendo los espacios iniciales de cada línea, que es justo la trampa: indenta el literal para que coincida con tu código y esa indentación queda dentro del texto. Cuando es la primera instrucción de una función, clase o módulo, Python la guarda como el docstring de ese objeto (la documentación que muestra help()), así que la convención es poner ahí un resumen breve. Para indentar un bloque entre comillas triples de modo que coincida con su entorno sin que la indentación se filtre al valor, quítala en tiempo de ejecución con textwrap.dedent(). Las comillas triples ''' y """ funcionan igual; """ es la convención.

python
message = """
Estimada Ana,

Gracias por tu pedido.

Saludos,
El Equipo
"""
JunoStrings de varias líneas Tres comillas en cada extremo permiten que un string se extienda por varias líneas, y Python conserva cada salto de línea y espacio exactamente como los escribiste. Recurre a ellas siempre que tengas un bloque de texto, como un mensaje o una plantilla, que no entra cómodamente en una sola línea.
JunoStrings de varias líneas Las comillas triples conservan saltos de línea y espacios literalmente, así que son ideales para plantillas de correo, SQL, y cualquier bloque largo. También es así como funcionan los docstrings: un string entre comillas triples al inicio de una función o clase se convierte en su documentación en línea. Cuidado con la indentación, porque los espacios que agregas para alinearlo terminan dentro del texto.
JunoStrings de varias líneas Todo dentro de las comillas triples se conserva literalmente, espacios iniciales incluidos, que es la trampa: indenta el literal para que coincida con tu código y esa indentación termina en el valor. Pon uno breve al inicio de una función o clase y se convierte en el docstring que muestra help(). Cuando lo necesites indentado en el código fuente pero limpio en el valor, pásalo por textwrap.dedent().

Secuencias de escape ​

Algunos caracteres son difíciles de escribir directamente dentro de un string. Python usa secuencias de escape: una barra invertida seguida de una letra que representa algo. Las dos que vas a usar constantemente son \n para un salto de línea y \t para una tabulación.

Las secuencias de escape te permiten incrustar caracteres que de otro modo romperían la sintaxis o que no se pueden escribir directamente. Las que vas a usar seguido: \n (salto de línea), \t (tabulación), \\ (una barra invertida literal), \" y \' (comillas dentro de un string con el mismo delimitador). Las rutas de Windows requieren barras invertidas, lo cual choca con el procesamiento de escapes. Antepón r para desactivarlo.

Más allá de los cotidianos \n y \t, Python admite escapes Unicode para caracteres que no puedes escribir directamente: \uXXXX y \UXXXXXXXX nombran un carácter por su número, y \N{name} lo nombra en palabras, como \N{GREEK SMALL LETTER ALPHA}. El que conviene usar en código real es el string crudo (raw string), escrito r"...", que desactiva por completo el manejo de escapes y pasa cada barra invertida sin modificarla. Úsalo para rutas de Windows y para patrones de expresiones regulares, donde las barras invertidas están pensadas para ese consumidor y no para Python, y donde olvidar la r produce patrones que silenciosamente coinciden con lo equivocado.

SecuenciaCarácter
\nSalto de línea
\tTabulación
\\Barra invertida literal
\"Comilla doble
\'Comilla simple
python
print("Line one\nLine two")        # dos líneas de salida
print("Name:\tAna")                # Name:   Ana
path = r"C:\Users\Ana\Documents"   # string crudo, sin procesamiento de escapes
JunoSecuencias de escape Una barra invertida dentro de un string significa "lee el siguiente carácter de forma especial": \n inicia una línea nueva, \t inserta una tabulación, \\ es una barra invertida real. Esas dos, \n y \t, son las que realmente vas a escribir. Pon una r antes de la comilla y las barras invertidas vuelven a ser simples, útil para rutas de Windows.
JunoSecuencias de escape\n, \t, \\ y \" cubren los escapes de todos los días. El que te evita dolores de cabeza: un string crudo, r"...", apaga el procesamiento de escapes para que cada barra invertida se mantenga literal. Úsalo en rutas de Windows y patrones de regex, donde las barras invertidas están pensadas para algo distinto de Python.
JunoSecuencias de escape Más allá de \n y \t existen escapes Unicode como \N{name}, pero el que más se usa es el string crudo r"...", que pasa cada barra invertida sin tocarla. Úsalo en patrones de regex y rutas de Windows, porque olvidarlo te da un patrón que silenciosamente coincide con lo equivocado en vez de un error que te avise.

Verificar el contenido de un string ​

Python tiene métodos que responden preguntas de sí/no sobre lo que contiene un string. Devuelven True o False. El más útil al principio: isdigit() te permite verificar si un string son todos números antes de convertirlo, así evitas que se caiga con una entrada inesperada.

Cada método is* verifica una propiedad específica de todo el string y devuelve True solo si cada carácter cumple la condición. Su uso principal es validar entradas: verifica antes de convertir para evitar que se caiga con una entrada inesperada. isdigit() antes de int() es el patrón clásico, una alternativa a capturar el ValueError que se cubre en el capítulo de Files and exceptions.

Estas verificaciones preguntan "¿es cada carácter de este tipo?" en todo Unicode, no solo en las letras y dígitos ASCII comunes. Eso significa que "2".isdigit() es True tanto para el dos en superíndice como para el "2" normal, lo cual puede dejar pasar entradas sorprendentes por una verificación de validación. Cuando te refieras estrictamente a los dígitos del 0 al 9, combina s.isascii() and s.isdigit(). isnumeric() es aún más amplio, ya que cuenta fracciones y otros caracteres con valor numérico, así que recurre a la verificación más restringida que coincida con lo que realmente aceptas, en lugar de la primera que parezca correcta.

python
"42".isdigit()       # True
"hello".isalpha()    # True
"hello42".isalnum()  # True
"   ".isspace()      # True
"Hello".islower()    # False
"HELLO".isupper()    # True
JunoVerificar el contenido de un string Los métodos is* responden preguntas de sí o no y devuelven True solo cuando cada carácter cumple. El que vas a usar primero: llama a isdigit() antes de int() para asegurarte de que el texto realmente sea un número, así una entrada rara no te hace fallar.
JunoVerificar el contenido de un string Cada método is* es True solo si todo el string cumple, lo cual los hace útiles para validar entradas antes de convertirlas. isdigit() antes de int() es la guardia clásica. Recuerda que está evaluando el string completo, así que un string vacío devuelve False en todos los casos.
JunoVerificar el contenido de un string Estas verificaciones abarcan todo Unicode, no solo ASCII simple, así que isdigit() deja pasar superíndices y otros caracteres numéricos que quizás no querías aceptar. Cuando te refieras a los dígitos del 0 al 9, combínalo: s.isascii() and s.isdigit(). Elige la verificación más restringida que coincida con tu entrada real, en vez de la primera que se vea parecida.

En la práctica ​

Elimina espacios, normaliza mayúsculas y minúsculas, y luego extrae lo que necesitas. Esta secuencia maneja casi cualquier texto proporcionado por el usuario:

python
raw_input = "  [email protected]  "
email = raw_input.strip().lower()   # "[email protected]"

at_pos = email.find("@")
username = email[:at_pos]
domain = email[at_pos + 1:]

print(f"User:   {username}")    # "ana"
print(f"Domain: {domain}")      # "ejemplo.com"

Armar una URL a partir de sus partes y validarla y analizarla de inmediato:

python
BASE_URL = "https://api.example.com"
version = "v2"
resource = "users"
user_id = 42

url = f"{BASE_URL}/{version}/{resource}/{user_id}"
# "https://api.example.com/v2/users/42"

parts = url.split("://")              # ["https", "api.example.com/v2/users/42"]
protocol = parts[0]                   # "https"
secured = url.startswith("https")
domain = parts[1].split("/")[0]       # "api.example.com"

print(f"Protocol : {protocol}")
print(f"Secure   : {secured}")
print(f"Domain   : {domain}")

Analizar una línea de log estructurada usando find(), slicing y alineación de f-string:

python
log_entry = "[2024-01-15 09:42:11] ERROR: File not found: report.csv"

timestamp = log_entry[1:20]
rest = log_entry[22:]                # "ERROR: File not found: report.csv"
colon_pos = rest.find(":")
level = rest[:colon_pos]             # "ERROR"
message = rest[colon_pos + 2:]       # "File not found: report.csv"

print(f"[{timestamp}] {level:>8}: {message}")
# [2024-01-15 09:42:11]    ERROR: File not found: report.csv

find() ubica el límite, el slicing extrae las partes, y el format spec >8 alinea a la derecha la etiqueta de severidad para que las columnas se mantengan consistentes cuando los nombres de nivel difieren en longitud.

Referencia de métodos ​

MétodoQué hace
.lower() / .upper()Convierte a minúsculas / mayúsculas
.title() / .capitalize()Capitaliza cada palabra / solo la primera
.strip() / .lstrip() / .rstrip()Elimina espacios en blanco alrededor
.find(sub)Índice de la primera coincidencia, o -1
.count(sub)Cuántas veces aparece sub
.startswith(s) / .endswith(s)Verificación de prefijo / sufijo
.replace(old, new)Reemplaza ocurrencias
.split(sep)Divide en una lista
sep.join(iterable)Une elementos en un string
.isdigit() / .isalpha() / .isalnum()Verificaciones de tipo de carácter