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