¿Por qué llamar a un método de cadena (como .replace) no modifica (muta) la cadena? ¿Por qué no cambia a menos que asigne el resultado?

2 minutos de lectura

Avatar de usuario de Katherina
Katherina

Intento hacer un reemplazo de cadena simple, pero no sé por qué no parece funcionar:

X = "hello world"
X.replace("hello", "goodbye")

quiero cambiar la palabra hello a goodbyepor lo que debería cambiar la cadena "hello world" a "goodbye world". Pero X solo permanece "hello world". ¿Por qué mi código no funciona?

Avatar de usuario de Tadeck
Tadeck

Esto es porque las cadenas son inmutables en Python.

Lo que significa que X.replace("hello","goodbye") devoluciones una copia de X con reemplazos hechos. Por eso necesitas reemplazar esta línea:

X.replace("hello", "goodbye")

con esta línea:

X = X.replace("hello", "goodbye")

Mas ampliamente, esto es cierto para todos los métodos de cadena de Python que cambian el contenido de una cadena “in situ”p.ej replace,strip,translate,lower/upper,join,…

Debes asignar su salida a algo si quieres usarlo y no tirarlo, por ejemplo

X  = X.strip(' \t')
X2 = X.translate(...)
Y  = X.lower()
Z  = X.upper()
A  = X.join(':')
B  = X.capitalize()
C  = X.casefold()

y así.

  • Punto pedante: las cadenas se pueden mutar para x += 'a' caso especial, por ejemplo, stackoverflow.com/a/40996908/6260170

    – Chris_Rands

    8 oct 2018 a las 15:24

  • @Chris_Rands: parece que tiene razón, pero desde el exterior no tiene un efecto de mutabilidad real: algunas implementaciones verifican si esto se usa realmente, y si no (para que no se observe la mutabilidad), en realidad mutaría. ¿Es eso cierto?

    – Tadeck

    9 oct 2018 a las 16:35

  • @Tadeck Bueno, creo que lo es real pero es simplemente una optimización de CPython y no es directamente relevante aquí (por eso dije que estaba siendo pedante)

    – Chris_Rands

    11/10/2018 a las 20:29

Todas las funciones de cadena como lower, upper, strip están devolviendo una cadena sin modificar el original. Si intenta modificar una cadena, como podría pensar well it is an iterablefallará.

x = 'hello'
x[0] = 'i' #'str' object does not support item assignment

Hay una buena lectura sobre la importancia de que las cadenas sean inmutables: ¿Por qué las cadenas de Python son inmutables? Las mejores prácticas para usarlos

Avatar de usuario de paDrEdadash
paDrEdadash

Ejemplo para métodos de cadena

Dada una lista de nombres de archivo, queremos cambiar el nombre de todos los archivos con extensión hpp a la extensión h. Para hacer esto, nos gustaría generar una nueva lista llamada newfilenames, que consta de los nuevos nombres de archivo.

filenames = ["program.c", "stdio.hpp", "sample.hpp", "a.out", "math.hpp", "hpp.out"]
# Generate newfilenames as a list containing the new filenames
# using as many lines of code as your chosen method requires.
newfilenames = []
for i in filenames:
    if i.endswith(".hpp"):
        x = i.replace("hpp", "h")
        newfilenames.append(x)
    else:
        newfilenames.append(i)


print(newfilenames)
# Should be ["program.c", "stdio.h", "sample.h", "a.out", "math.h", "hpp.out"]

  • que tiene que ver esto con la pregunta

    – Boris Verjovskiy

    20 mayo 2021 a las 19:34

¿Ha sido útil esta solución?