è possibile utilizzare una funzione di ricorsione come segue:
Nota: L'argomento risultato sarà trattata come una variabile globale (perché passando oggetto mutabile alla funzione influisce il chiamante)
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)
risultato:
[['ACGT', (5, 13)], ['GT', (19, 25)], ['TATACG', (29, 41)]]
risposta alla precedente domanda per la seguente stringa:
s = 'AAAC**ACGTACGTA**ATTCC**GTGTGT**CCCC**TATACGTATACG**TTT'
È possibile utilizzare entrambe le risposte da mentioned question e alcune ricette in più:
In primo luogo è possibile dividere la stringa con **
quindi creare un nuovo elenco contiene le corde ripetuti con r'(.+)\1+'
regex:
Così il risultato sarà:
>>> new=[re.search(r'(.+)\1+',i).group(0) for i in s.split('**')]
>>> new
['AAA', 'ACGTACGT', 'TT', 'GTGTGT', 'CCCC', 'TATACGTATACG', 'TTT']
Nota su 'ACGTACGT'
che mancato il A
alla fine!
Quindi è possibile utilizzare la funzione 's principal_period
per ottenere le stringhe ripetute sub:
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)
...
in modo da avere le stringhe ripetute in l
e principali stringhe in sub
:
>>> l
['ACGT', 'GT', 'TATACG']
>>> sub
['ACGTACGT', 'GTGTGT', 'TATACGTATACG']
Poi si è necessario il region
che si può fare con il metodo span
:
>>> for t in sub:
... regons.append(re.search(t,s).span())
>>> regons
[(6, 14), (24, 30), (38, 50)]
E alla fine si può comprimere il 3 lista regon
, sub
, l
e utilizzare una comprensione dict per creare il risultato atteso:
>>> 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}}
Il codice principale:
>>> 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}}
Penso che usino qualcosa chiamato "suffisso tree" per questo ... ma non è molto semplice ... e ogni volta che comincio a farlo, mi metto in giro a metà strada https://www.cs.cmu.edu/ ~ ckingsf/bioinfo-lectures/suffixtrees.pdf –
Cosa contate come * "motivi ripetitivi" *? Se ''GT'' conta, perché non ad es. ''**'', ''TT'' o'' CC''? E qual è esattamente la tua domanda? – jonrsharpe
''ACGT'' non si ripete 2 volte,' ACGTACGTA' ha un 'A' alla fine !! – Kasramvd