Являются ли строки (str) в Python изменяемыми (mutable)?

Ответ

Нет, строки в Python неизменяемы (immutable). Это фундаментальное свойство типа str. После создания строкового объекта его содержимое изменить невозможно. Любая операция, модифицирующая строку, возвращает новый строковый объект.

Примеры, демонстрирующие неизменяемость:

s = "hello"

# Попытка изменить символ по индексу вызовет ошибку
s[0] = "H"  # TypeError: 'str' object does not support item assignment

# Операции, создающие новые строки:
new_s = s.replace("h", "H")  # "Hello" — это новый объект
print(s)        # Оригинал остался "hello"
print(new_s)    # "Hello"

concatenated = "H" + s[1:]  # Конкатенация создаёт новую строку "Hello"
upper_s = s.upper()         # "HELLO" — новый объект

Практическое следствие и обходной путь: Поскольку строки неизменяемы, частые операции конкатенации в цикле (s += "part") создают множество временных объектов и неэффективны. Для сборки строки из многих частей используйте метод .join():

# Неэффективно:
result = ""
for chunk in list_of_strings:
    result += chunk

# Эффективно:
result = "".join(list_of_strings)

Если требуется работать с изменяемой последовательностью символов, можно преобразовать строку в список, изменить его и собрать обратно:

s_list = list("hello")
s_list[0] = "H"  # Изменение списка разрешено
s_new = "".join(s_list)  # "Hello"

Ответ 18+ 🔞

А, ну это же классика, ёпта! Строки в Python — они как священная корова, их не тронь. Создал — и всё, приехали. Изменить символ внутри нельзя, хоть тресни. Любая попытка — сразу TypeError в морду, типа "не поддерживает присваивание по индексу, идиот".

Смотри, вот живой пример, чтобы совсем понятно было:

s = "hello"

# Попробуй первую букву на большую поменять — получишь по шапке
s[0] = "H"  # TypeError: 'str' object does not support item assignment

# Все эти методы типа replace, upper — они не исходную строку меняют, а новую создают
new_s = s.replace("h", "H")  # "Hello" — это уже другой объект, совсем другой!
print(s)        # Оригинал так и остался "hello", не тронут
print(new_s)    # А вот это уже "Hello"

# Даже конкатенация — и та плодит новую строку
concatenated = "H" + s[1:]  # Собрали "Hello" из кусочков, но это новый продукт
upper_s = s.upper()         # "HELLO" — опять новенький, с завода

А теперь самое важное, чувак. Поскольку строка — штука неизменяемая, если ты будешь в цикле её пилить конкатенацией (s += "часть"), то Python будет каждый раз создавать новый объект, а старый выкидывать. Для одной-двух операций — похуй, но если частей овердохуища, то производительность накроется медным тазом. Терпения ноль ебать, пока всё посчитается.

Поэтому умные дяди придумали метод .join(). Вот как правильно:

# Так делать — пиздец как неэффективно, не повторяй:
result = ""
for chunk in list_of_strings:
    result += chunk  # Каждый раз новая строка, старые в мусорку

# А вот так — быстро и элегантно, как швейцарские часы:
result = "".join(list_of_strings)

Ну а если тебе прям позарез нужно поковыряться в символах, как в массиве? Без проблем! Преврати строку в список, там делай что хочешь, а потом обратно собери:

s_list = list("hello")  # Разобрали на буковки
s_list[0] = "H"         # Меняй что угодно, список-то изменяемый
s_new = "".join(s_list) # Собрали обратно — получили "Hello"

Вот и вся магия. Строки — они как девственницы, их не перепишешь. Можно только создать новую, с исправлениями. Запомни это, и будет тебе счастье.