In Python, strings are iterable and there is no included function to reverse a string. One rationale for excluding a string.reverse() method is to give Python developers an incentive to leverage the power of this special circumstance. Each character in a string may be easily handled as part of a sequence of elements, much like arrays in other languages.
So, how would you reverse a string in Python?
The quickest way to reverse a string in Python is to use a slice that steps by -1:
'Test string'[::-1]
In Python, the str object does not include a built-in reverse function.
If you’re teaching yourself to code, here are a couple things about Python's strings that you should be aware of:
Slice notation is simple once you wrap your head around it. The subscript in ‘Test string’[subscript] creates a slice when a colon is included in the square brackets:
It follows the format below:
string[start:stop:step]
The start segment specifies the starting integer where the slicing will begin. It simply defaults to None if nothing is specified, corresponding to starting at the first element. Similarly, if no stop command is specified, the slicing will default to None, corresponding to ending at the last element. The step will default to None, corresponding to a step size of 1.
Here, we have only specified -1 as the step. A negative value will make the slicing reverse through the sequence. -1 will go through every item in the sequence backward, and -2 would go through every second item in the sequence backward.
For example let’s use slice notation and see what the console output becomes:
print('Test string'[1::])
Here the output starts at index value of 1.
Output: est string
Now, let’s change the start value to negative.
print('Test string'[-1::])
With a negative start, we start at the last index value minus one and get the following:
Output: g
Let’s change the stop value to 1.
print('Test string'[:1:])
With a stop value of 1, the output stops after the first character:
Output: T
Let’s change the stop value to negative.
print('Test string'[:-1:])
With a stop value of negative 1, the output stops at one less the maximum index value of the string:
Output: Test string
With the step value set to positive 1, we receive a copy of the string.
print('Test string'[::1])
Output: Test string
It follows that when we set the step value to negative 1, we receive a copy of the string, but reversed.
print('Test string'[::-1])
Output: gnirts tseT
To improve readability, it’s recommended that you put this in a function
def reverse_string(string):
return string[::-1]
This way, you can call this function later in your code as many times as needed. For example, to print a reversed string to the console you would use the following code:
print(reverse_string(‘Test string’))
The console readout would be:
gnirts tseT
For reference, here is the code all together:
def reverse_string(string):
return string[::-1]
print(reverse_string('Test string'))
If you need to create a slice outside of the square brackets, then you'll need to create a slice object and specify None where applicable:
slice_object = slice(None,None,-1)
print('Test string'[slice_object])
Slice objects can be reused multiple times and their values can be changed. They could come in handy depending on what the desired outcome of your code is!
Alternatively, you can call the join() method with the reversed() function, which takes all elements in an iterable object and combines them into one string while reversing them.
def reverse_string(string):
return ''.join(reversed(string))
print(reverse_string('Test string'))
The console output:
gnirts tseT
The '' in the code below simply indicates what separator is used when joining the strings. If you use the following code:
def reverse_string(string):
return '!'.join(reversed(string))
print(reverse_string('Test string'))
You’ll receive the following reversed output instead:
g!n!i!r!t!s! !t!s!e!T
Slice notation in Python might be difficult to comprehend for some users and developers who do not wish to put in a lot of effort.
However, once the fundamental concepts are understood, this technique's dominance over fixed-string manipulation techniques may be quite significant.
If you're not sure what alternatives are available, don't worry; there are a variety of strategies to reverse strings in Python. Lambda functions, iterators, and simple one-off function declarations are just a few examples. Developers may also construct their own string.reverse() function, although understanding the many aspects of this programming language can be beneficial.
Here is a simple for loop in a function to reverse a string in Python that starts with declaring your variables:
def reverse_string(string):
reversed_string = ""
for x in string:
reversed_string = x+reversed_string
return(reversed_string)
print(reverse_string('Test string'))
The output is the same reversed string as before:
gnirts tseT
What’s happening is that the for loop is iterating through every character in “Test string.”
After the first loop we have the first character “T”:
reversed_string =T+””
And then reversed_string is set to T, after the second pass we have the second character in “Test string”, which is “e”:
reversed_string =e+T
Thus, reversed_string is set to eT, and after the second pass through the for loop we have:
reversed_string =s+eT
So reversed_string is set to seT, and so on.
To employ programming best practices, it’s best to start with an empty string and create a new string from the old one. This task can be accomplished by using pure syntax and literals inside a while loop:
def reverse_string(string):
reversed_string = ''
index = len(string)
while index:
index -= 1
reversed_string += string[index]
return reversed_string
print(reverse_string('Test string'))
Your console output will be:
gnirts tseT
However, this method has a downside of its own because, remember, in Python, strings are immutable. This means that in each situation where it appears as if you're appending a character to your new_string, Python is actually creating a new string. However, in certain circumstances such as these, Python knows how to optimize this so the processing time won’t increase with many repetitions and large computations.
Let’s break down the functions in this code sample.
Element |
T |
e |
s |
t |
|
s |
t |
r |
i |
n |
g |
Index Value |
0 |
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
Theoretically, it would be even better to collect all the newly created strings in a list, and use the join() method on them later to avoid creating a new string every time with the following:
def reverse_string(string):
created_strings = []
index = len(string)
while index:
index -= 1
created_strings.append(string[index])
return ''.join(created_strings)
print(reverse_string('Test string'))
This makes use of the append() method, which adds a new element to the end of the list instead of using the operator +=.
So far, all the methods above are correct only if Unicode Modifiers and grapheme clusters are ignored. For example, the following emojis have multiple modifiers π¨π©π¦πΆ (Family: Man, Woman, Boy, Baby) and π¨π¨π¦ (Family: Man, Man, Boy).
Let’s try to reverse the following string: π¨π¨π¦π¨π©π¦πΆ
If you use the above methods you’ll get the below console output:
π¦π¨π¨πΆπ¦π©π¨
This is a string of a Boy, Man and Man, Baby, Boy, Woman and Man, the modifiers were reversed resulting in the graphemes becoming separated.
There is a package to correctly handle graphemes. It can be installed via the command line with pip installer. In Python 3.9.7 the command to install the grapheme package is:
py -m pip install grapheme
If this doesn’t work for you, try to update pip with:
py -m pip install --upgrade pip setuptools wheel
The Python code to correctly reverse strings with emojis requires the grapheme package, and the process is much the same as before:
import grapheme
def reverse_emojis(string):
g = list(grapheme.graphemes(string))
return ''.join(g[::-1])
print(reverse_emojis("π¨π©π¦πΆπ¨π¨π¦"))
The printed console output with this function will be:
π¨π¨π¦π¨π©π¦πΆ
This answer performs the slowest out of all the presented solutions so far. It might be simpler and faster to just throw an error if the inputted string contains an emoji. In the command line, be sure to install the emoji and regex packages to determine if the string contains an emoji:
py -m pip install emoji
py -m pip install regex
Then we can create a function that can test if any character in the string contains an emoji with the below code:
import emoji
import regex
def contains_emoji(string):
emoji_list = []
data = regex.findall(r'\X', string)
for string in data:
if any(char in emoji.UNICODE_EMOJI['en'] for char in string):
emoji_list.append(string)
if len(emoji_list)>0:
return(bool(True))
else:
return(bool(False))
We would have to add this check for the other operations to ensure that graphemes and emojis are handled correctly when reversed. We can run the string through this check, and if it contains an emoji we would perform the grapheme reversal, and if it did not we would perform one of the other faster solutions to optimize processing speed. Here is the complete solution:
import emoji
import regex
string = "Test string πΌπ¨π©π¦πΆ" #This is the test string
def reverse_string(string): #Using reversal method from “The Alternate No Slice Answer”
reversed_string = ""
for x in string:
reversed_string = x+reversed_string
return(reversed_string)
def contains_emoji(string):
emoji_list = []
data = regex.findall(r'\X', string)
for string in data:
if any(char in emoji.UNICODE_EMOJI['en'] for char in string):
emoji_list.append(string)
return(len(emoji_list))
if contains_emoji(string)==0:
print(reverse_string(string))
print("Does not contain emojis.")
else:
print(reverse_emojis(string))
print("Contains emojis.")
The console output is as follows:
π¨π©π¦πΆπΌ gnirts tseT
Contains emojis.
And if we change the test string value to a string that does not contain emojis:
string = "Test string"
Then we receive the below console output:
gnirts tseT
Does not contain emojis.
This final method is the most robust and would offer fast processing speed with a great number of randomly generated iterations. Typically, emojis are restricted characters for most usages so this level of care is normally not required for working models for reversing a string in Python. With more extensive tests, The Alternate No Slice Answer seemed to perform the fastest.