0

Say I have the string

s = 'x x x x x'

I want to randomly change one of the 'x' to y

s2 = 'x x y x x'

x and y will be multiple characters long.

If I just wanted to change the first instance of x, I would use string.replace, but how can I change a random instance?

5
  • Is this only for cases of strings with a sequence of one character type separated by spaces? Commented Nov 4, 2013 at 16:49
  • Are the tokens (xx, yy, ...) always separated by exactly one space? Commented Nov 4, 2013 at 16:49
  • They are not cleanly separated, it could be arbitrary characters eg sentences, with x and y being multiple words. Commented Nov 4, 2013 at 16:50
  • 2
    Then please give an example of the strings you're actually dealing with. Commented Nov 4, 2013 at 16:51
  • Are the random substrings of fixed lengths or variable? Commented Nov 4, 2013 at 16:52

2 Answers 2

4

You could use re.finditer to retrieve the start/end of all possible matches and do an appropriate replacement. This will cover variable length replacing, but does mean you need to be wary of re syntax for the frm argument.

import re
from random import choice

def replace_random(src, frm, to):
    matches = list(re.finditer(frm, src))
    replace = choice(matches)
    return src[:replace.start()] + to + src[replace.end():]

Example:

>>> [replace_random('x x x x x', r'\bx\b', 'y') for _ in range(10)]
['y x x x x', 'x x x x y', 'x x y x x', 'x y x x x', 'x x x y x', 'x x x y x', 'x x y x x', 'x y x x x', 'x x x x y', 'x x y x x']
Sign up to request clarification or add additional context in comments.

5 Comments

You could always re.escape frmif you want it to behave like a str.replace.
@mgilson Yep... for production purposes it should probably be documented that it's expected an actual regex pattern be supplied... unless the OP prefers adding another option which enables the function to behave in two modes... but that's probably just confusing...
I think if you would use needle, haystack and replacement as variable names it could also make the example a bit more clear - but maybe that's just my personal preference.
Exactly what I wanted, thank you. On the last line, it should be src, not s though.
@user2953349 errr yes... not sure how I copied/pasted that wrongly, but corrected :) Thanks.
2

you can do

import random

def replace_random(string, str_a, str_b):
    rand = max(random.randint(0, string.count(str_a)), 1)
    return string.replace(str_a, str_b, rand).replace(str_b, str_a, rand - 1)

print replace_random('x x x x x', 'x', 'y')

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.