В Python строки (str) являются неизменяемыми объектами, то есть после создания изменить их содержимое невозможно. Любая операция, модифицирующая строку (например, конкатенация или замена символов), создает новый объект строки. Это обеспечивает безопасность и предсказуемость работы, так как вам не нужно беспокоиться, что кто-то неявно изменит строку в другой части кода.
s = 'Hello' s2 = s.replace('H', 'J') # s останется 'Hello', а s2 будет 'Jello'
В отличие от строк, списки в Python — объекты изменяемые. Их содержимое можно менять на месте через индексацию или методы, что иногда приводит к неявным эффектам, если один и тот же список используют в разных местах.
С точки зрения производительности: если нужно часто модифицировать большие строки (например, в цикле), механика неизменяемости может привести к излишней аллокации памяти и медленной работе кода. В таких случаях рекомендуется использовать список для накопления фрагментов строки, а затем объединять их через ''.join().
Пример:
# Плохо (медленно для больших объемов данных): s = '' for word in words: s += word # На каждом шаге создается новая строка # Хорошо: parts = [] for word in words: parts.append(word) s = ''.join(parts)
Вопрос: Почему следующий код "s += 'abc'" быстрее, чем "s = s + 'abc'" для строк?
Ответ: Такие вопросы задают, чтобы проверить, понимает ли человек, что обе операции на самом деле равнозначны для строк (s += 'abc' создаёт новый объект, как и s = s + 'abc') — так устроено поведение типов в Python. Для списков поведение иное, ведь list += [...] мутирует объект, а list = list + [...] создаёт новый. Для строк это всегда новая строка.
s = 'hi' s += 'abc' # Новый объект, исходная строка не изменяется def compare(s): a = s a += 'abc' # id(a) != id(s) <-- разные объекты в памяти
История
На проекте, где требовалась обработка больших логов (разбор строк длиной в сотни мегабайт), разработчик использовал наивную конкатенацию строк в цикле. Итог — огромные просадки по производительности и быстрый рост потребления памяти. После оптимизации через список и join() время выполнения уменьшилось в 20 раз.
История
В одном проекте, при попытке "исправить" символ в строке по индексу, программист ожидал увидеть изменение исходной строки. Возникла ошибка TypeError: 'str' object does not support item assignment. Потратив несколько часов, отладчику пришлось создавать новую строку с помощью срезов и заменить нужный символ.
История
При передаче строк в функцию для их "дополнения" (например, добавить суффикс к каждому элементу из списка), один из разработчиков ожидал, что строка изменится "на месте". Итог — функция возвращала None (из-за отсутствия return), а все строки оставались оригинальными.