while the preceding code fragment accomplishes the goalit may be terribly inefficient because strings are immutablethe commandletters +cwould presumably compute the concatenationletters cas new string instance and then reassign the identifierlettersto that result constructing that new string would require time proportional to its length if the final result has charactersthe series of concatenations would take time proportional to the familiar sum nand therefore ( time inefficient code of this type is widespread in pythonperhaps because of the somewhat natural appearance of the codeand mistaken presumptions about how the +operator is evaluated with strings some later implementations of the python interpreter have developed an optimization to allow such code to complete in linear timebut this is not guaranteed for all python implementations the optimization is as follows the reason that commandletters +ccauses new string instance to be created is that the original string must be left unchanged if another variable in program refers to that string on the other handif python knew that there were no other references to the string in questionit could implement +more efficiently by directly mutating the string (as dynamic arrayas it happensthe python interpreter already maintains what are known as reference counts for each objectthis count is used in part to determine if an object can be garbage collected (see section but in this contextit provides means to detect when no other references exist to stringthereby allowing the optimization more standard python idiom to guarantee linear time composition of string is to use temporary list to store individual piecesand then to rely on the join method of the str class to compose the final result using this technique with our previous example would appear as followstemp for in documentif isalpha)temp append(cletters join(tempstart with empty list append alphabetic character compose overall result this approach is guaranteed to run in (ntime firstwe note that the series of up to append calls will require total of (ntimeas per the definition of the amortized cost of that operation the final call to join also guarantees that it takes time that is linear in the final length of the composed string as we discussed at the end of the previous sectionwe can further improve the practical execution time by using list comprehension syntax to build up the temporary listrather than by repeated calls to append that solution appears asletters join([ for in document if isalpha)]better yetwe can entirely avoid the temporary list with generator comprehensionletters join( for in document if isalpha)