Best way to loop over a python string backwards
Question:
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
Answers:
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
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.
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.
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.
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.
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
def reverse(text):
x = ""
for i in range(len(text)):
x = x + text[len(text)-i-1]
return x
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
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.
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
If you care about performance, its best to not use reversed
as this will generate a new string and an unnecessary function call. Instead, just iterate backwards through the string.
Eg. This will find last newline in a string:
s = 'abcdefgnxyz'
for i in range(len(s)-1, -1, -1):
if s[i] == 'n':
print('found \n at %s' % i)
break
# found n at 7
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
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
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.
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.
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.
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.
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
def reverse(text):
x = ""
for i in range(len(text)):
x = x + text[len(text)-i-1]
return x
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
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.
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
If you care about performance, its best to not use reversed
as this will generate a new string and an unnecessary function call. Instead, just iterate backwards through the string.
Eg. This will find last newline in a string:
s = 'abcdefgnxyz'
for i in range(len(s)-1, -1, -1):
if s[i] == 'n':
print('found \n at %s' % i)
break
# found n at 7