В целом, стандарт языка Python здесь не дает никаких гарантий; на самом деле, как определено, строки неизменяемы, и то, что вы делаете , должно кусать вас в любом случае, так как вы написали форму Алгоритм Шлемьеля-живописца .
Но в первом случае, как деталь реализации, CPython (справочный интерпретатор) поможет вам и объединит строку на месте (технически нарушая гарантию неизменности) при некоторых довольно специфических условиях, которые позволяют ему придерживаться дух правил неизменности. Наиболее важным условием является то, что на соединяемую строку следует ссылаться только в одном месте (если это не так, другая ссылка изменится на месте, нарушив видимость неизменности str
). Присваивая str2 = str1
после каждой конкатенации, вы гарантируете, что при конкатенации будет две ссылки, поэтому при каждой конкатенации должен быть сделан новый str
, чтобы сохранить кажущуюся неизменность строк , Это означает больше выделения и освобождения памяти, большее (и постепенно увеличивающееся) количество копий памяти и т. Д.
Обратите внимание, что полагаться на эту оптимизацию явно не рекомендуется в PEP 8, руководстве по стилю Python :
Код должен быть написан так, чтобы не мешать другим реализациям Python (PyPy, Jython, IronPython, Cython, Psyco и т. Д.).
Например, не полагайтесь на эффективную реализацию CPython конкатенации строк на месте для операторов в форме a += b
или a = a + b
. Эта оптимизация хрупка даже в CPython (она работает только для некоторых типов) и совсем не присутствует в реализациях, которые не используют пересчет. В чувствительных к производительности частях библиотеки следует использовать форму ''.join()
. Это гарантирует, что объединение происходит в линейное время в разных реализациях.
Важное замечание о "работает только для некоторых типов". Эта оптимизация относится только к str
; в Python 2 он не работает на unicode
(хотя * Python 3 str
основан на реализации unicode
в Python 2), а в Python 3 он не работает на bytes
(которые похожи на Python 2 str
под капотом).