In Python, strings (str) are immutable objects, meaning their content cannot be changed once created. Any operation that modifies a string (such as concatenation or character replacement) creates a new string object. This ensures safety and predictability in operation, as you do not have to worry that someone will implicitly change the string in another part of the code.
s = 'Hello' s2 = s.replace('H', 'J') # s remains 'Hello', and s2 will be 'Jello'
Unlike strings, lists in Python are mutable objects. Their content can be changed in place through indexing or methods, which can sometimes lead to implicit effects if the same list is used in different places.
From a performance perspective: if you need to frequently modify large strings (for example, in a loop), the mechanics of immutability can lead to excessive memory allocation and slow performance. In such cases, it is recommended to use a list to accumulate string fragments and then join them using ''.join().
Example:
# Bad (slow for large data volumes): s = '' for word in words: s += word # A new string is created at each step # Good: parts = [] for word in words: parts.append(word) s = ''.join(parts)
Question: Why is the following code "s += 'abc'" faster than "s = s + 'abc'" for strings?
Answer: Such questions are asked to check if the person understands that both operations are indeed equivalent for strings (s += 'abc' creates a new object, just like s = s + 'abc') — this is how type behavior works in Python. For lists, the behavior is different since list += [...] mutates the object, whereas list = list + [...] creates a new one. For strings, it is always a new string.
s = 'hi' s += 'abc' # New object, original string remains unchanged def compare(s): a = s a += 'abc' # id(a) != id(s) <-- different objects in memory
Story
In a project that required processing large logs (parsing strings hundreds of megabytes long), a developer used naive string concatenation in a loop. The result was a huge drop in performance and a rapid increase in memory consumption. After optimizing through a list and join(), the execution time decreased by 20 times.
Story
In one project, when trying to "fix" a character in a string by index, a programmer expected to see a change in the original string. An error occurred: TypeError: 'str' object does not support item assignment. After spending several hours, the debugger had to create a new string using slicing and replace the desired character.
Story
When passing strings to a function for their "completion" (for example, adding a suffix to each item in a list), one of the developers expected the string to change "in place". The result was that the function returned None (due to the absence of return), and all strings remained original.