How to Reverse a String in Python An overview of the three main ways to reverse a Python string: “slicing”, reverse iteration, and the classic in-place reversal algorithm. Also includes performance benchmarks.

What’s the best way to reverse a string in Python? Granted, string reversal isn’t used all that often in day-to-day programming, but it’s a popular interviewing question: # You have this: 'TURBO' # And you want that: 'OBRUT' One variation of this question is to write a function that checks whether a given string is a palindrome, that is, whether or not it reads the same forwards and backwards: def is_palindrome ( string ): reversed_string = # ??? return string == reversed_string >>> is_palindrome ( 'TACOCAT' ) True >>> is_palindrome ( 'TURBO' ) False Clearly, we’ll need to figure out how to reverse a string to implement this is_palindrome function in Python…so how do you do it? Python’s str string objects have no built-in .reverse() method like you might expect if you’re coming to Python from a different language, like Java or C#—the following approach will fail: >>> 'TURBO' . reverse () Traceback (most recent call last): File "<stdin>" , line 1 , in <module> AttributeError : 'str' object has no attribute 'reverse' In this tutorial you’ll learn the three major ways to reverse strings in Python:

Option 1: Reversing a Python String With the “ [::-1] ” Slicing Trick Strings follow the sequence protocol in Python. And all sequences support an interesting feature called slicing. You can view slicing as an extension of the square-brackets indexing syntax. It includes a special case where slicing a sequence with “ [::-1] ” produces a reversed copy. Because Python strings are sequences this is a quick and easy way to get a reversed copy of a string: >>> 'TURBO' [:: - 1 ] 'OBRUT' Of course, you can wrap this (slightly unwieldy) slicing expression into a named function to make it more obvious what the code does: def reverse_string1 ( s ): """Return a reversed copy of `s`""" return s [:: - 1 ] >>> reverse_string1 ( 'TURBO' ) 'OBRUT' So, how do you like this solution? It’s short and sweet—but, in my mind, the biggest downside to reversing a string with the slicing syntax is that it uses an advanced Python feature that some developers would say is “arcane.” I don’t blame them—list slicing can be difficult to understand the first time you encounter its quirky and terse syntax. When I’m reading Python code that makes use of slicing I often have to slow down and concentrate to “mentally parse” the statement, to make sure I understand what’s going on. My biggest gripe here is that the “ [::-1] ” slicing syntax doesn’t communicate clearly enough that it creates a reversed copy of the original string. For this reason I feel like using Python’s slicing feature to reverse a string is a decent solution, but it can be a difficult to read to the uninitiated. [ You can learn more about slicing in this article. ] Moving on…

Option 2: Reversing a Python String Using reversed() and str.join() Reversing a string using reverse iteration with the reversed() built-in is another option. You get a reverse iterator you can use to cycle through the elements in the string in reverse order: >>> for elem in reversed ( 'TURBO' ): ... print ( elem ) O B R U T Using reversed() does not modify the original string (which wouldn’t work anyway as strings are immutable in Python.) What happens is that you get a “view” into the existing string you can use to look at all the elements in reverse order. This is a powerful technique that takes advantage of Python’s iterator protocol. So far, all you saw was how to iterate over the characters of a string in reversed order. But how can you use this technique to create a reversed copy of a Python string with the reversed() function? Here’s how: >>> '' . join ( reversed ( 'TURBO' )) 'OBRUT' This code snippet used the .join() method to merge all of the characters resulting from the reversed iteration into a new string. Pretty neat, eh? Of course, you can once again extract this code into a separate function to create a proper “reverse string” function in Python. Here’s how: def reverse_string2 ( s ): """Return a reversed copy of `s`""" return "" . join ( reversed ( s )) >>> reverse_string2 ( 'TURBO' ) 'OBRUT' I really like this reverse iterator approach for reversing strings in Python. It communicates clearly what is going on, and even someone new to the language would intuitively understand that I’m creating a reversed copy of the original string. And while understanding how iterators work at a deeper level is helpful, it’s not absolutely necessary to use this technique. One more approach you should check out:

Option 3: The “Classic” In-Place String Reversal Algorithm Ported to Python This is the “classic” textbook in-place string reversal algorithm, ported to Python. Because Python strings are immutable, you first need to convert the input string into a mutable list of characters, so you can perform the in-place character swap: def reverse_string3 ( s ): """Return a reversed copy of `s`""" chars = list ( s ) for i in range ( len ( s ) // 2 ): tmp = chars [ i ] chars [ i ] = chars [ len ( s ) - i - 1 ] chars [ len ( s ) - i - 1 ] = tmp return '' . join ( chars ) >>> reverse_string3 ( 'TURBO' ) 'OBRUT' As you can tell, this solution is quite unpythonic and not very idiomatic at all. It doesn’t play to Python’s strengths and it’s basically a straight port of a C algorithm. And if that wasn’t enough—it’s also the slowest solution, as you’ll see in the next section where I’ll do some benchmarking on these three implementations.

Performance Comparison After implementing the string reversal approaches I showed you in this tutorial I became curious about what their relative performance would be. So I set out to do some benchmarking: >>> import timeit >>> s = 'abcdefghijklmnopqrstuvwxyz' * 10 >>> timeit . repeat ( lambda : reverse_string1 ( s )) [ 0.6848115339962533 , 0.7366074129968183 , 0.7358982900041156 ] >>> timeit . repeat ( lambda : reverse_string2 ( s )) [ 5.514941683999496 , 5.339547180992668 , 5.319950777004124 ] >>> timeit . repeat ( lambda : reverse_string3 ( s )) [ 48.74324739299482 , 48.637329410004895 , 49.223478018000606 ] Well, that’s interesting…Here are the results in table form: Algorithm Execution Time Slowdown Slicing 0.72s 1x reversed + join 5.39s 7.5x Classic / In-Place 48.87s 67.9x As you can see, there’s a massive performance gap between these three implementations. Slicing is the fastest approach, reversed() is 8x slower than slicing, and the “classic” in-place algorithm is a whopping 71x slower in this benchmark! Now, the in-place swap could definitely be optimized (leave a comment below with your improved solution if you want)—but this performance comparison still gives us a decent idea of which string reversal operation is the fastest in Python.