Extra space added on reverse string function

Viewed 418

I'm trying to figure out how to reverse a string using Python without using the [::-1] solution.

My code seems to work fine for several test cases, but it adds an extra space for one instance and I can't figure out why.

def reverse(s):
    r = list(s)
    start, end = 0, len(s) - 1
    x = end//2
    for i in range(x):
        r[start], r[end] = r[end], r[start]
        start += 1
        end -= 1

    print(''.join(r))


reverse('A man, a plan, a canal: Panama')

# returns 'amanaP :lanac  a,nalp a ,nam A'
# note the double space ^^ - don't know why


reverse('a monkey named fred, had a banana')

# 'returns ananab a dah ,derf deman yeknom a'


reverse('Able was I ere I saw Elba')

# returns 'ablE was I ere I saw elbA'
4 Answers

Change

    x = end//2

to

    x = len(s)//2

The bug appears to be related to the handling of even-length strings. A much easier way to build a string reverse function would be:

def reverse(s):
    result = ""
    for character in reversed(s):  #Reversed returns an object that, when used in a for loop, outputs each object of a string, list, or other iterable, in reverse order.
        result += character #Add that character back to the result.
    return result

This function works regardless of string length. I hope this helps.

Using the technique you're using it's probably clearer to test start agains end directly rather than trying to manage lengths and indexes. You can do that with while start < end:. For example:

def reverse(s):
    r = list(s)
    start, end = 0, len(s) - 1
    while start < end:
        r[start], r[end] = r[end], r[start]
        start += 1
        end -= 1

    print(''.join(r))

reverse('A man, a plan, a canal: Panama')

prints

amanaP :lanac a ,nalp a ,nam A

Your bug is in the boundary condition for an even-length string:

start, end = 0, len(s) - 1
x = end//2
for i in range(x):

For instance, with 8 characters, your for iterator is (range(3)), which gets you only the first three positions.

You fail to swap the middle pair.

The "clean" way to fix this is to change your x calculation:

x = (end+1) // 2

or, as others have said

x = len(s) // 2
Related