How to replace two things at once in a string?

Say I have a string, "ab".

I want to replace "a" with "b" and "b" with "a" in one swoop.

So in the end, the string should be "ba" and not "aa" or "bb" and not use more than one line. Is this doable?

Answers:

Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.

Method 1

When you need to swap variables, say x and y, a common pattern is to introduce a temporary variable t to help with the swap: t = x; x = y; y = t.

The same pattern can also be used with strings:

>>> # swap a with b
>>> 'obama'.replace('a', '%temp%').replace('b', 'a').replace('%temp%', 'b')
'oabmb'

This technique isn’t new. It is described in PEP 378 as a way to convert between American and European style decimal separators and thousands separators (for example from 1,234,567.89 to 1.234.567,89. Guido has endorsed this as a reasonable technique.

Method 2

import string
"abaababb".translate(string.maketrans("ab", "ba"))
# result: 'babbabaa'

Note that this only works for one-character substitutions.

For longer substrings or substitutions, this is a bit complex, but might work:

import re

def replace_all(repls, str):
    # return re.sub('|'.join(repls.keys()), lambda k: repls[k.group(0)], str)                                     
    return re.sub('|'.join(re.escape(key) for key in repls.keys()),
                  lambda k: repls[k.group(0)], str)                                     


text =  "i like apples, but pears scare me"
print replace_all({"apple": "pear", "pear": "apple"}, text)

Unfortunately this won’t work if you include any regexp special characters you can’t use regexps this way 🙁

(Thanks @TimPietzcker)

Method 3

If you are OK with two lines, this is more elegant.

d={'a':'b','b':'a'}
''.join(d[s] for s in "abaababbd" if s in d.keys())

Method 4

>>> import re
>>> re.sub('.', lambda m: {'a':'b', 'b':'a'}.get(m.group(), m.group()), 'abc')
'bac'

Method 5

Your example is a little bit abstract but in the past I’ve used this recipe which builds a regular expression to do single-pass multiple replace. Here’s my tweaked version of it:

import re 

def multiple_replace(dict, text): 
  regex = re.compile("|".join(map(re.escape, dict.keys())))
  return regex.sub(lambda mo: dict[mo.group(0)], text)

Note that the keys (searchstrings) are re.escaped.

In your case it would be:

from utils import multiple_replace

print multiple_replace({
    "a": "b",
    "b": "a"
}, "ab")

UPDATE:

By now this is basically the same as Amadan’s answer

Method 6

the_string="ab"
new_string=""

for x in range(len(the_string)):
    if the_string[x]=='a':
        new_string+='b'
        continue
    if the_string[x]=='b':
        new_string+='a'
        continue
    new_string+=the_string[x]

the_string=new_string

print the_string


All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

0 0 votes
Article Rating
Subscribe
Notify of
guest

0 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
0
Would love your thoughts, please comment.x
()
x