Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What's the best way to "periodically" replace characters in a string in Python?

I have a string where a character ('@') needs to be replaced by characters from a list of one or more characters "in order" and "periodically". So for example I have

'ab@cde@@fghi@jk@lmno@@@p@qrs@tuvwxy@z'

and want

'ab1cde23fghi1jk2lmno312p3qrs1tuvwxy2z'

for replace_chars = ['1', '2', '3']

The problem is that in this example there are more @ in the string than I have replacers.

This is my try:

result = ''
replace_chars = ['1', '2', '3']
string = 'ab@cde@@fghi@jk@lmno@@@p@qrs@tuvwxy@z'

i = 0
for char in string:
    if char == '@':
        result += replace_chars[i]
        i += 1
    else:
        result += char

print(result)

but this only works of course if there are not more than three @ in the original string and otherwise I get IndexError.

Edit: Thanks for the answers!

like image 870
FirimaElda Avatar asked Mar 07 '16 21:03

FirimaElda


1 Answers

Your code could be fixed by adding the line i = i%len(replace_chars) as the last line of your if clause. This way you will be taking the remainder from the division of i by the length of your list of replacement characters.

The shorter solution is to use a generator that periodically spits out replacement characters.

>>> from itertools import cycle
>>> s = 'ab@cde@@fghi@jk@lmno@@@p@qrs@tuvwxy@z'
>>> replace_chars = ['1', '2', '3']
>>>
>>> replacer = cycle(replace_chars)
>>> ''.join([next(replacer) if c == '@' else c for c in s])
'ab1cde23fghi1jk2lmno312p3qrs1tuvwxy2z'

For each character c in your string s, we get the next replacement character from the replacer generator if the character is an '@', otherwise it just gives you the original character.

For an explanation why I used a list comprehension instead of a generator expression, read this.

like image 89
timgeb Avatar answered Oct 21 '22 19:10

timgeb