Best way to loop over a python string backwards
PythonStringOptimizationIteratorReversePython Problem Overview
What is the best way to loop over a python string backwards?
The following seems a little awkward for all the need of -1 offset:
string = "trick or treat"
for i in range(len(string)-1, 0-1, -1):
print string[i]
The following seems more succinct, but is it actually generate a reversed string so that there is a minor performance penalty?
string = "trick or treat"
for c in string[::-1]:
print c
Python Solutions
Solution 1 - Python
Try the reversed builtin:
for c in reversed(string):
print c
The reversed() call will make an iterator rather than copying the entire string.
PEP 322 details the motivation for reversed() and its advantages over other approaches.
Solution 2 - Python
EDIT: It has been quite some time since I wrote this answer. It is not a very pythonic or even efficient way to loop over a string backwards. It does show how one could utilize range and negative step values to build a value by looping through a string and adding elements in off the end of the string to the front of the new value. But this is error prone and the builtin function reversed is a much better approach. For those readers attempting to understand how reversed
is implemented, take a look at the PEP, number 322, to get an understanding of the how and why. The function checks whether the argument is iterable and then yields
the last element of a list until there are no more elements to yield. From the PEP:
> [reversed] makes a reverse iterator over sequence objects that support getitem() and len().
So to reverse a string, consume the iterator until it is exhausted. Without using the builtin, it might look something like,
def reverse_string(x: str) -> str:
i = len(x)
while i > 0:
i -= 1
yield x[i]
Consume the iterator either by looping, eg
for element in (reverse_string('abc')):
print(element)
Or calling a constructor like:
cba = list(reverse_string('abc'))
The reverse_string
code is almost identical to the PEP with a check removed for simplicity's sake. In practice, use the builtin.
ORIGNAL ANSWER:
Here is a way to reverse a string without utilizing the built in features such as reversed
. Negative step values traverse backwards.
def reverse(text):
rev = ''
for i in range(len(text), 0, -1):
rev += text[i-1]
return rev
Solution 3 - Python
Yes, the second syntax shortcut creates an intermediate string and has an associated performance penalty.
The first version is better written as:
for index, char in enumerate(reversed(s)):
print "pos %d: %s" % (index, char)
Which is easy to comprehend. Neither reversed
nor enumerate
` need to make a copy of the string.
Also be careful about using string
as a variable name, as it is also the name of a module in the standard library.
Solution 4 - Python
reversed
takes an iterable and and returns an iterator that moves backwards. string[::-1]
is fine, but it creates a new, reversed string instead. If you just want to iterate, then this will probably better:
for c in reversed(string):
print c
If you want to use the reversed string afterwards, creating it once will be better.
Solution 5 - Python
string = "trick or treat"
for c in string[::-1]:
print c
I would use that. It is probably quite fast although there may be a slightly better way (but I doubt it).
EDIT:
Actually, with a second test using a program I hacked together, reversed
is probably the way to go.
==== Results ====
Sample 1: 0.0225071907043 # Using a for loop
Sample 2: 0.0100858211517 # Using reversed
Solution 6 - Python
Less code is usually faster in Python. Luckily, you don't have to guess:
python -mtimeit -s"s='x'*100000" "for x in s[::-1]: pass"
100 loops, best of 3: 1.99 msec per loop
python -mtimeit -s"s='x'*100000" "for x in reversed(s): pass"
1000 loops, best of 3: 1.97 msec per loop
python -mtimeit -s"s='x'*100000" "for i in xrange(len(s)-1, 0-1, -1): s[i]"
100 loops, best of 3: 4.95 msec per loop
So the shorter code is a bit faster, but it comes with a memory overhead.
Solution 7 - Python
string = "trick or treat"
for c in reversed(string):
print c
Will do what I think you want. It uses an iterator. This should work with anything that has _reveresed_() or _len_() and _getitem_() implemented. _getitem_() would have to take int arguments starting at 0.
Solution 8 - Python
def reverse(text):
x = ""
for i in range(len(text)):
x = x + text[len(text)-i-1]
return x
Solution 9 - Python
Reverse a String in Python using For Loop
outputStr = ''
a = raw_input("Enter String: ")
for i in range(len(a), 0, -1):
outputStr += a[i-1]
print outputStr
Solution 10 - Python
Python 3 with enumerate
and reversed
methods:
string = "trick or treat"
for i, c in enumerate(reversed(string)):
print(i, c)
You can use print(c) just for retrieving each character without the index.
Solution 11 - Python
string reverse
def reverse(a_string):
rev = ''
for i in range(len(a_string)-1, -1, -1):
rev = rev + a_string[i]
return rev
print(reverse("This string should be reversed!"))
output is: !desrever eb dluohs gnirts sihT