There is no built in reverse
function for Python's str
object. What is the best way of implementing this method?
If supplying a very concise answer, please elaborate on its efficiency. For example, whether the str
object is converted to a different object, etc.
s = 'Hello world'
s[::-1]
in the above example label s or variable s is holding string which contain Hello world string and on second step i m printing reverse of Hello world string by taking starting from everything to everything in reverse step order with -1.
This is also an interesting way:
or similar:
Another more 'exotic' way using byterarray which supports .reverse()
will produce:
My own experience with this question is academic. However, if you're a pro looking for the quick answer, use a slice that steps by
-1
:or more readably (but slower due to the method name lookups and the fact that join forms a list when given an iterator),
str.join
:or for readability and reusability, put the slice in a function
and then:
Longer explanation
If you're interested in the academic exposition, please keep reading.
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:
The subscript creates a slice by including a colon within the braces:
To create a slice outside of the braces, you'll need to create a slice object:
A readable approach:
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:Most performant approach:
Much faster is using a reverse slice:
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.
Implement as Function
To actually implement this as a function, I think it is semantically clear enough to simply use a descriptive name:
And usage is simply:
What your teacher probably wants:
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:
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:
However, as we will see in the timings below for CPython, this actually takes longer, because CPython can optimize the string concatenation.
Timings
Here are the timings:
CPython optimizes string concatenation, whereas other implementations may not:
@Paolo's
s[::-1]
is fastest; a slower approach (maybe more readable, but that's debatable) is''.join(reversed(s))
.This is simple and meaningful reverse function, easy to understand and code
How about:
This is extended slice syntax. It works by doing
[begin:end:step]
- by leaving begin and end off and specifying a step of -1, it reverses a string.