Чому виклик методу рядка Python не робить нічого, якщо ви не призначите його вихід?


136

Я намагаюся зробити просту заміну рядків, але я не знаю, чому це, здається, не працює:

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

Я хочу змінити слово helloна goodbye, таким чином воно повинно змінити рядок "hello world"на "goodbye world". Але Х просто залишається "hello world". Чому мій код не працює?

Відповіді:


232

Це тому, що струни незмінні в Python .

Що означає, що X.replace("hello","goodbye")повертає копію Xіз зробленими замінами . Через це вам потрібно замінити цей рядок:

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

за допомогою цього рядка:

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

У більш широкому сенсі, це вірно для всіх строкових методів Python , що змінити вміст струни «на місці» , наприклад replace, strip, translate, lower/ upper, join...

Ви повинні призначити їх вихід чомусь, якщо ви хочете використовувати його, а не викидати його, наприклад

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

і так далі.


1
Pedantic точка: рядки можуть мутувати для x += 'a'особливого випадку, наприклад , stackoverflow.com/a/40996908/6260170
Chris_Rands

@Chris_Rands: Схоже, ви маєте рацію, але ззовні це не має справжнього ефекту зміни мутаційності - деякі програми перевіряють, чи справді це використовується, і якщо ні (так що не змінюватимуться), він насправді мутуватиме. Це правда?
Тадек

@ Tadeck Добре, я думаю, що це реально, але це просто оптимізація CPython і тут не має безпосереднього значення (саме тому я сказав, що я був педантичним)
Chris_Rands

0

Всі рядкові функції , як lower, upper, stripповертається рядок без зміни оригіналу. Якщо ви спробуєте змінити рядок, як ви могли подумати well it is an iterable, вона не вдасться.

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

Про те, як важливо, щоб струни були незмінні, добре читаємо: Чому струни Python незмінні? Найкращі практики їх використання

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.