I'm trying to use the function str.replace(",", ";"[, count])
but when i fill in count (let's say 1) it only changes the first ","
but i want to change a certain "," (working with boundries)` does anyone have a idea on how to do this?
Asked
Active
Viewed 196 times
1

lode
- 13
- 3
-
Possible duplicate of [Right-to-left string replace in Python?](http://stackoverflow.com/questions/9943504/right-to-left-string-replace-in-python) – dstudeba Oct 08 '15 at 19:18
-
It's unclear if you want to change all of them, just the last, or certain one? Maybe show a better example. – l'L'l Oct 08 '15 at 19:20
-
@I'L'I I'm sorry i was a bit unclear, i need to change a certain on (working with boundry) – lode Oct 08 '15 at 19:30
2 Answers
3
You could rsplit
and join:
s = "foo,foobar,foo"
print(";".join(s.rsplit(",",1)))
Or reverse the string, replace and reverse again:
print(s[::-1].replace(";",",",1)[::-1])
splitting actually seems a little faster:
In [7]: timeit s[::-1].replace(";",",",1)[::-1]
1000000 loops, best of 3: 521 ns per loop
In [8]: timeit ";".join(s.rsplit(",",1))
1000000 loops, best of 3: 416 ns per loop
If you want to change the ith occurrence:
def change_ith(st, ith, sep, rep):
return "".join([s + rep if i == ith else s + sep
for i, s in enumerate(st.split(sep, ith), 1)]).rstrip(sep)
Output:
In [15]: s = "foo,foo,bar,foo,foo"
In [16]: change_ith(s, 1, ",",";")
Out[16]: 'foo;foo,bar,foo,foo'
In [17]: change_ith(s, 2, ",",";")
Out[17]: 'foo,foo;bar,foo,foo'
In [18]: change_ith(s, 3, ",",";")
Out[18]: 'foo,foo,bar;foo,foo'
In [19]: change_ith(s, 4, ",",";")
Out[19]: 'foo,foo,bar,foo;foo'
There are cases where join will could give incorrect output if you had a string ending in the sep and a few other edge cases, to get a more robust function we would need to use a regex passing a lambda as the repl arg and using itertools.count
to count how many matches we got:
import re
from itertools import count
def change_ith(st, ith, sep, rep):
return re.sub(sep, lambda m, c=count(1): rep if next(c) == ith else m.group(0), st)
Or applying the same logic to join:
from itertools import count
def change_ith(st, ith, sep, rep):
cn = count(1)
return "".join([rep if ch == sep and next(cn) == ith else ch
for ch in st])

Padraic Cunningham
- 176,452
- 29
- 245
- 321
-
Thanks for that tip but is it also possible to change a middel ","? (with a boundry or something?) – lode Oct 08 '15 at 19:22
-
@Lode, for more complex patterns you would probably use a regex, it would be possible without but a bit ugly – Padraic Cunningham Oct 08 '15 at 19:24
-
@lode, no worries, I added a couple of more robust options incuding a regex approach – Padraic Cunningham Oct 08 '15 at 20:02
-
This was for a school project so i don't think imports are allowed but thanks for the answer – lode Oct 08 '15 at 20:36
0
You should reverse, replace, and reverse again. I use reverse indexing for that in the example below:
s = "one, two, three, four, five"
print str.replace(s[::-1], ',', ';', 1)[::-1]

heltonbiker
- 26,657
- 28
- 137
- 252