If you’re interested in the academic exposition, please keep reading.
There is no built-in reverse function in Python’s str object.
Here is a couple of things about Python’s strings you should know:
In Python, strings are immutable. Changing a string does not modify the string. It creates a new one.
Strings are sliceable. Slicing a string gives you a new string from one point in the string, backwards or forwards, to another point, by given increments. They take slice notation or a slice object in a subscript:
string[subscript]
The subscript creates a slice by including a colon within the braces:
string[start:stop:step]
To create a slice outside of the braces, you’ll need to create a slice object:
While ''.join(reversed('foo')) is readable, it requires calling a string method, str.join, on another called function, which can be rather relatively slow. Let’s put this in a function – we’ll come back to it:
But how can we make this more readable and understandable to someone less familiar with slices or the intent of the original author? Let’s create a slice object outside of the subscript notation, give it a descriptive name, and pass it to the subscript notation.
If you have an instructor, they probably want you to start with an empty string, and build up a new string from the old one. You can do this with pure syntax and literals using a while loop:
def reverse_a_string_slowly(a_string):
new_string = ''
index = len(a_string)
while index:
index -= 1 # index = index - 1
new_string += a_string[index] # new_string = new_string + character
return new_string
This is theoretically bad because, remember, strings are immutable – so every time where it looks like you’re appending a character onto your new_string, it’s theoretically creating a new string every time! However, CPython knows how to optimize this in certain cases, of which this trivial case is one.
Best Practice
Theoretically better is to collect your substrings in a list, and join them later:
def reverse_a_string_more_slowly(a_string):
new_strings = []
index = len(a_string)
while index:
index -= 1
new_strings.append(a_string[index])
return ''.join(new_strings)
However, as we will see in the timings below for CPython, this actually takes longer, because CPython can optimize the string concatenation.
CPython optimizes string concatenation, whereas other implementations may not:
… do not rely on CPython’s efficient implementation of in-place string concatenation for statements in the form a += b or a = a + b . This optimization is fragile even in CPython (it only works for some types) and isn’t present at all in implementations that don’t use refcounting. In performance sensitive parts of the library, the ”.join() form should be used instead. This will ensure that concatenation occurs in linear time across various implementations.
This answer is provided to address the following concern from @odigity:
Wow. I was horrified at first by the solution Paolo proposed, but that
took a back seat to the horror I felt upon reading the first
comment: “That’s very pythonic. Good job!” I’m so disturbed that such
a bright community thinks using such cryptic methods for something so
basic is a good idea. Why isn’t it just s.reverse()?
Problem
Context
Python 2.x
Python 3.x
Scenario:
Developer wants to transform a string
Transformation is to reverse order of all the characters
Developer might expect something like string.reverse()
The native idiomatic (aka “pythonic“) solution may not be readable to newer developers
Developer may be tempted to implement his or her own version of string.reverse() to avoid slice notation.
The output of slice notation may be counter-intuitive in some cases:
see e.g., example02
print 'coup_ate_grouping'[-4:] ## => 'ping'
compared to
print 'coup_ate_grouping'[-4:-1] ## => 'pin'
compared to
print 'coup_ate_grouping'[-1] ## => 'g'
the different outcomes of indexing on [-1] may throw some developers off
Rationale
Python has a special circumstance to be aware of: a string is an iterable type.
One rationale for excluding a string.reverse() method is to give python developers incentive to leverage the power of this special circumstance.
In simplified terms, this simply means each individual character in a string can be easily operated on as a part of a sequential arrangement of elements, just like arrays in other programming languages.
To understand how this works, reviewing example02 can provide a good overview.
The cognitive load associated with understanding how slice notation works in python may indeed be too much for some adopters and developers who do not wish to invest much time in learning the language.
Nevertheless, once the basic principles are understood, the power of this approach over fixed string manipulation methods can be quite favorable.
For those who think otherwise, there are alternate approaches, such as lambda functions, iterators, or simple one-off function declarations.
If desired, a developer can implement her own string.reverse() method, however it is good to understand the rationale behind this aspect of python.
The existing answers are only correct if Unicode Modifiers / grapheme clusters are ignored. I’ll deal with that later, but first have a look at the speed of some reversal algorithms:
You can see that the time for the list comprehension (reversed = string[::-1]) is in all cases by far the lowest (even after fixing my typo).
String Reversal
If you really want to reverse a string in the common sense, it is WAY more complicated. For example, take the following string (brown finger pointing left, yellow finger pointing up). Those are two graphemes, but 3 unicode code points. The additional one is a skin modifier.
example = "👈🏾👆"
But if you reverse it with any of the given methods, you get brown finger pointing up, yellow finger pointing left. The reason for this is that the “brown” color modifier is still in the middle and gets applied to whatever is before it. So we have
All of the above solutions are perfect but if we are trying to reverse a string using for loop in python will became a little bit tricky so here is how we can reverse a string using for loop
string ="hello,world"
for i in range(-1,-len(string)-1,-1):
print (string[i],end=(" "))
I hope this one will be helpful for someone.
回答 16
这是我的风格:
def reverse_string(string):
character_list =[]for char in string:
character_list.append(char)
reversed_string =""for char in reversed(character_list):
reversed_string += char
return reversed_string
def reverse_string(string):
character_list = []
for char in string:
character_list.append(char)
reversed_string = ""
for char in reversed(character_list):
reversed_string += char
return reversed_string
回答 17
反向字符串有很多方法,但我也创建了另一种方法只是为了好玩。我认为这种方法还不错。
def reverse(_str):
list_char = list(_str)# Create a hypothetical list. because string is immutablefor i in range(len(list_char)/2):# just t(n/2) to reverse a big string
list_char[i], list_char[-i -1]= list_char[-i -1], list_char[i]return''.join(list_char)print(reverse("Ehsan"))
There are a lot of ways to reverse a string but I also created another one just for fun. I think this approach is not that bad.
def reverse(_str):
list_char = list(_str) # Create a hypothetical list. because string is immutable
for i in range(len(list_char)/2): # just t(n/2) to reverse a big string
list_char[i], list_char[-i - 1] = list_char[-i - 1], list_char[i]
return ''.join(list_char)
print(reverse("Ehsan"))
With python 3 you can reverse the string in-place meaning it won’t get assigned to another variable. First you have to convert the string into a list and then leverage the reverse() function.