how to replace pairwise characters in a string using Python

285 Views Asked by At

Suppose I have a string :

x="AAAABBABAABCCABBCA"

and I have the following information :

AAA=1
ABB= ignore/remove from final output
ABA=2
ABC=3
CAB=4
BCA= ignore/remove from final output

so when I translate x the output y should be: y=1234

I tried:

def fun(x):
    x=x.replace("AAA","1") 
    x=x.replace("ABA","2")
    x=x.replace("ABB","")
    x=x.replace("ABC","3")
    x=x.replace("BCA","")
    x=x.replace("CAB","4")
    print x

But it is giving me the wrong answer: 123CCA

I also tried:

def fun(x):
    z=[]
        for i in range(0,(len(x)+1)):
            if i=="AAA":
                i=i.replace("AAA",1)
        z.append(i)
        elif i=="ABA":
            i=i.replace("ABA",2)
    elif i=="ABB":
            i=i.replace("ABB","")
    elif i=="ABC":
            i=i.replace("ABC",3)
    elif i=="BCA":
            i=i.replace("BCA","")
    elif i=="CAB":
            i=i.replace("CAB","4")
        z.append(i)
    print ",".join(z)

But there is something wrong with the syntax.

So the main problem is to check the string from the beginning and replace the characters. Please help me.

Thanks

3

There are 3 best solutions below

1
On BEST ANSWER

Here's a solution that will properly print 1234 when run over your string :

x = "AAAABBABAABCCABBCA"
newstr = ''
for i in range(0,len(x),3):
    part = x[i:i + 3]
    if part == 'AAA':
        newstr += '1'
    elif part == 'ABA':
        newstr += '2'
    elif part == 'ABC':
        newstr += '3'
    elif part == 'CAB':
        newstr += '4'
print newstr

If a sequence of three characters doesn't do anything, there's not much point in having it check for it; just quietly continue on to the next one.

If you have your heart set on using str.replace to replace these strings within your code, you should look at the optional third parameter count. If you limit it to a single replacement each loop, you should achieve your desired result.

0
On

As a pythonic way you can use a grouper function to group your string based on a specific length and put your patterns within a dictionary :

>>> d ={'ABA': '2', 'ABB': '', 'ABC': '3', 'AAA': '1', 'BCA': '', 'CAB': '4'}
>>> def grouper(iterable, n, fillvalue=None):
...     "Collect data into fixed-length chunks or blocks"
...     # grouper('ABCDEFG', 3, 'x') --> ABC DEF Gxx
...     args = [iter(iterable)] * n
...     return izip_longest(fillvalue=fillvalue, *args)
... 
>>> from itertools import izip_longest 

>>> ''.join([d.get(''.join(i),'') for i in grouper(x,3)])
'1234'
2
On

You should use a dict to store your rules, so that you don't have to keep updating your code every time your rule changes. You can simply update the rules dictionary and your function should keep working.

rules = {'AAA': '1',
         'ABB': '',
         'ABA': '2',
         'ABC': '3',
         'CAB': '4',
         'BCA': ''}

def fun(str, rules=rules, substr_length=3):
    newstr = []
    for i in range(0, len(str), substr_length):
        substr = str[i:i+substr_length]
        newstr.append(rules[substr])

    return ''.join(newstr)

print fun("AAAABBABAABCCABBCA")