String reversal maintaining spaces and capitalization

Viewed 97

The function I am writing needs to reverse a string while maintaining the spaces' positions as well as the positions of capitalization. Thus when the input is "I lovE Python" the output will be "N htyP Evoli"

def program(x):
  n = len(x)
  y = x.lower()
  result = [0]*n

  for i in range(n):
    if x[i] == ' ':
      result[i] = ' '
    else:
      if (x[i].isupper() == True):
          if (y[n-i]==' '):
            result[i] = y[n-i-1].upper()
          else:
            result[i] = y[n-i].upper() 
      else:
          if (y[n-i]==' '):
            result[i] = y[n-i-1]
          else:
            result[i] = y[n-i]
        
  return ''.join(str(v) for v in result)

I get an index out of bounds error due to the result[i] = y[n-i-1] code; however, if I don't have that line the code adds an additional space depending on the string.

2 Answers

You could use a generator, and checks on the case:

s = "I lovE Python"

# i = reversed(s.replace(' ', '')) # line below is more efficient
i = filter(' '.__ne__, reversed(s))

''.join((next(i).upper() if c.isupper() else next(i).lower())
         if c != ' ' else c
         for c in s)

Output: 'N ohtY Pevoli'

Or a more classical loop (which will be more efficient as you only need to read once the reversed string):

s = "I lovE Python"
r = reversed(s)
out = [' ']*len(s)

for i,c in enumerate(s):
    if c != ' ':
        while (n:=next(r)) == ' ': # get the next non-space char
            continue
        out[i] = n.upper() if c.isupper() else n.lower()

''.join(out)

Try this:

def f(o,r):
    if o.isspace(): return o
    if r.isspace(): return ''
    return r.upper() if o.isupper() else r.lower()

s= 'I lovE Python'
r=''.join([f(o,r) for o,r in zip(s,s[::-1])])
# since [::-1] creates a copy of s more memory efficient will be
r=''.join([f(o,r) for o,r in zip(s,reversed(s))])
Related