Best way to loop over a python string backwards

PythonStringOptimizationIteratorReverse

Python 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

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionclwenView Question on Stackoverflow
Solution 1 - PythonRaymond HettingerView Answer on Stackoverflow
Solution 2 - PythonNathanView Answer on Stackoverflow
Solution 3 - PythonKenan BanksView Answer on Stackoverflow
Solution 4 - PythonCat Plus PlusView Answer on Stackoverflow
Solution 5 - PythonAJ00200View Answer on Stackoverflow
Solution 6 - PythonJochen RitzelView Answer on Stackoverflow
Solution 7 - PythonkrouseyView Answer on Stackoverflow
Solution 8 - PythonpraveenView Answer on Stackoverflow
Solution 9 - PythonAkshay MalhotraView Answer on Stackoverflow
Solution 10 - Pythonian0411View Answer on Stackoverflow
Solution 11 - PythonCodruta GulerView Answer on Stackoverflow