更复杂的版本"如何在Python中重复自己的字符串?"

Iva*_*tro 12 python string bioinformatics pattern-matching

我正在阅读这篇文章,我想知道是否有人能找到将重复图案捕捉到更复杂字符串的方法.

例如,找到所有重复的图案

string = 'AAACACGTACGTAATTCCGTGTGTCCCCTATACGTATACGTTT'
Run Code Online (Sandbox Code Playgroud)

这里重复的主题:'AAAC ACGTACGT AATTCC GTGTGT CCCC TATACGTATACG TTT'

所以,输出应该是这样的:

output = {'ACGT': {'repeat': 2,
                   'region': (5,13)},
          'GT': {'repeat': 3,
                 'region': (19,24)},
          'TATACG': {'repeat': 2,
                     'region': (29,40)}}
Run Code Online (Sandbox Code Playgroud)

该实例来自称为微卫星的典型生物现象,其存在于DNA中.

更新1:从字符串变量中删除了星号.那是一个错误.

更新2:单个字符图案不计算在内.例如:在ACGUG AAA GUC中,不考虑"A"主题.

Kas*_*mvd 4

您可以使用递归函数,如下所示:

注意:结果参数将被视为全局变量(因为将可变对象传递给函数会影响调用者)

import re
def finder(st,past_ind=0,result=[]):
   m=re.search(r'(.+)\1+',st)
   if m:
      i,j=m.span()
      sub=st[i:j]
      ind = (sub+sub).find(sub, 1)
      sub=sub[:ind]
      if len(sub)>1:
        result.append([sub,(i+past_ind+1,j+past_ind+1)])
      past_ind+=j
      return finder(st[j:],past_ind)
   else:
      return result



s='AAACACGTACGTAATTCCGTGTGTCCCCTATACGTATACGTTT'
print finder(s)
Run Code Online (Sandbox Code Playgroud)

结果:

[['ACGT', (5, 13)], ['GT', (19, 25)], ['TATACG', (29, 41)]]
Run Code Online (Sandbox Code Playgroud)

回答以下字符串的上一个问题:

s = 'AAAC**ACGTACGTA**ATTCC**GTGTGT**CCCC**TATACGTATACG**TTT'
Run Code Online (Sandbox Code Playgroud)

您可以使用上述问题的答案和一些额外的食谱:

首先,您可以使用 regex 分割字符串,**然后创建一个包含重复字符串的新列表r'(.+)\1+'

所以结果将是:

>>> new=[re.search(r'(.+)\1+',i).group(0) for i in s.split('**')]
>>> new
['AAA', 'ACGTACGT', 'TT', 'GTGTGT', 'CCCC', 'TATACGTATACG', 'TTT']
Run Code Online (Sandbox Code Playgroud)

注意,最后'ACGTACGT'错过了!A

然后你可以使用principal_periods 函数来获取重复的子字符串:

def principal_period(s):
    i = (s+s).find(s, 1, -1)
    return None if i == -1 else s[:i]

>>> for i in new:
...    p=principal_period(i)
...    if p is not None and len(p)>1:
...        l.append(p)
...        sub.append(i)
... 
Run Code Online (Sandbox Code Playgroud)

因此,您将在 中 得到重复字符串l,在 中 得到主字符串sub

>>> l
['ACGT', 'GT', 'TATACG']
>>> sub
['ACGTACGT', 'GTGTGT', 'TATACGTATACG']
Run Code Online (Sandbox Code Playgroud)

然后你需要一个region可以用span方法做到这一点的:

>>> for t in sub:
...    regons.append(re.search(t,s).span())

>>> regons
[(6, 14), (24, 30), (38, 50)]
Run Code Online (Sandbox Code Playgroud)

最后,您可以压缩 3 个列表regonsubl使用字典理解来创建预期结果:

>>> z=zip(sub,l,regons)
>>> out={i :{'repeat':i.count(j),'region':reg} for i,j,reg in z}
>>> out
{'TATACGTATACG': {'region': (38, 50), 'repeat': 2}, 'ACGTACGT': {'region': (6, 14), 'repeat': 2}, 'GTGTGT': {'region': (24, 30), 'repeat': 3}}
Run Code Online (Sandbox Code Playgroud)

主要代码:

>>> s = 'AAAC**ACGTACGTA**ATTCC**GTGTGT**CCCC**TATACGTATACG**TTT'
>>> sub=[]
>>> l=[]
>>> regon=[]
>>> new=[re.search(r'(.+)\1+',i).group(0) for i in s.split('**')]
>>> for i in new:
...    p=principal_period(i)
...    if p is not None and len(p)>1:
...        l.append(p)
...        sub.append(i)
... 

>>> for t in sub:
...    regons.append(re.search(t,s).span())
... 
>>> z=zip(sub,l,regons)
>>> out={i :{'repeat':i.count(j),'region':reg} for i,j,reg in z}
>>> out
{'TATACGTATACG': {'region': (38, 50), 'repeat': 2}, 'ACGTACGT': {'region': (6, 14), 'repeat': 2}, 'GTGTGT': {'region': (24, 30), 'repeat': 3}}
Run Code Online (Sandbox Code Playgroud)