# trying to reverse the string with "_" fixed at point

Stack Overflow Asked by saurabh on December 31, 2020

def r(s):
str = []
for i in len(s):
if (s[i]=='_'):
str = s[i] + str
continue
str = s[i] + str
return str

I tried using the above code to convert the following string

Input: ab_cde

Expected Output: ed_cba

def fixed_reverse(s, ch):
idxs = [-1] + [i for i, x in enumerate(s) if x == ch] + [len(s)]
idxs = [x - i + 1 for i, x in enumerate(idxs)]
chars = "".join(x for x in s if x != ch)[::-1]
return ch.join(chars[a:b] for a, b in zip(idxs[:-1], idxs[1:]))

>>> fixed_reverse("ab_cde_f_ghijk_l", "_")
'lk_jih_g_fedcb_a'

This works by:

1. Storing the locations of the fixed-point character "_".
2. Reversing the string with the "_" characters removed.
3. Inserting the "_" back into the correct locations.

Answered by Mateen Ulhaq on December 31, 2020

The main idea is to check all the positions of the underscore _, save them and reverse the string without them, to insert them again after reversing.

import re

def r(s):
# check where all the underscore are
underscore_positions = [m.start() for m in re.finditer('_', s)]
# get list of reversed chars without underscores
reversed_chars = [c for c in reversed(s) if c != '_']
# put underscore back where they where
for p in underscore_positions:
reversed_chars.insert(p, '_')
# profit
return "".join(reversed_chars)

The function can be modified to have a different fixed character.

I also uses the package re for the regex function to identify the _, you can do with a simple loop as underscore_positions = [i for i, c in enumerate(s) if c =='_'] if you prefer.

Answered by bracco23 on December 31, 2020

s = 'ab_cde'

out = ''
for a, b in zip(s, s[::-1]):
if b != '_' and a != '_':
out += b
else:
out += a

print(out)

Prints:

ed_cba

EDIT: For more fixed points:

s = 'ab_cde_f_ghijk_l'

i, out = iter(ch for ch in s[::-1] if ch != '_'), ''

out = ''.join(ch if ch == '_' else next(i) for ch in s)
print(out)

Prints:

lk_jih_g_fedcb_a

Answered by Andrej Kesely on December 31, 2020