Dlaczego wywołanie metody łańcuchowej w Pythonie nic nie robi, chyba że przypiszesz jej wyjście?

136

Próbuję wykonać prostą zamianę ciągu, ale nie wiem, dlaczego to nie działa:

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

Chcę zmienić słowo hellona goodbye, dlatego powinien zmienić ciąg "hello world"na "goodbye world". Ale X po prostu pozostaje "hello world". Dlaczego mój kod nie działa?

Katherina
źródło

Odpowiedzi:

232

Dzieje się tak, ponieważ w Pythonie ciągi znaków są niezmienne .

Co oznacza, że X.replace("hello","goodbye")zwraca kopię Xz dokonanymi wymianami . Z tego powodu musisz zamienić tę linię:

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

z tą linią:

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

Szerzej, to jest prawdziwe dla wszystkich metod ciąg Pythona, które zmieniają treść ciąg jest „w miejscu” , na przykład replace, strip, translate, lower/ upper,join ...

Musisz przypisać do czegoś ich wyjście, jeśli chcesz go używać i nie wyrzucać, np

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

i tak dalej.

Tadeck
źródło
1
Pedantyczny punkt: łańcuchy mogą być zmutowane do x += 'a'szczególnego przypadku, np stackoverflow.com/a/40996908/6260170
Chris_Rands
@Chris_Rands: Wygląda na to, że masz rację, ale z zewnątrz nie ma to rzeczywistego efektu zmienności - niektóre implementacje sprawdzają, czy jest to naprawdę używane, a jeśli nie (więc zmienność nie byłaby obserwowana), faktycznie mutowałaby. Czy to prawda?
Tadeck
@Tadeck Cóż, myślę, że to jest prawdziwe, ale to tylko optymalizacja CPythona i nie ma tutaj bezpośredniego związku (dlatego powiedziałem, że jestem pedantyczny)
Chris_Rands
0

Wszystkie funkcje łańcuchowe jako lower, upper, stripwracają ciąg bez modyfikowania oryginalnego. Jeśli spróbujesz zmodyfikować ciąg, jak możesz pomyśleć well it is an iterable, zakończy się to niepowodzeniem.

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

Jest dobra lektura o tym, jak ważne jest, aby ciągi znaków były niezmienne: Dlaczego ciągi znaków w Pythonie są niezmienne? Najlepsze praktyki dotyczące ich używania

user1767754
źródło