查找每个字母至少重复一次的正则表达式
Finding regular expression with at least one repetition of each letter
从任何 *.fasta DNA 序列(仅 'ACTG' 个字符)中,我必须找到每个字母至少包含一次重复的所有序列。
例如从序列 'AAGTCCTAG' 我应该能够找到:'AAGTC'、'AGTC'、'GTCCTA'、'TCCTAG'、'CCTAG'和 'CTAG'(每个字母的迭代)。
我不知道如何在 pyhton 2.7 中做到这一点。我正在尝试使用正则表达式,但它并没有搜索所有变体。
我怎样才能做到这一点?
如果您可以将序列分解成一个列表,例如5 个字母的序列,然后您可以使用此函数查找重复序列。
from itertools import groupby
import numpy as np
def find_repeats(input_list, n_repeats):
flagged_items = []
for item in input_list:
# Create itertools.groupby object
groups = groupby(str(item))
# Create list of tuples: (digit, number of repeats)
result = [(label, sum(1 for _ in group)) for label, group in groups]
# Extract just number of repeats
char_lens = np.array([x[1] for x in result])
# Append to flagged items
if any(char_lens >= n_repeats):
flagged_items.append(item)
# Return flagged items
return flagged_items
#--------------------------------------
test_list = ['aatcg', 'ctagg', 'catcg']
find_repeats(test_list, n_repeats=2) # Returns ['aatcg', 'ctagg']
您可以找到所有长度为 4+ 的子字符串,然后从中向下 select 以仅找到包含每个字母之一的最短可能组合:
s = 'AAGTCCTAG'
def get_shortest(s):
l, b = len(s), set('ATCG')
options = [s[i:j+1] for i in range(l) for j in range(i,l) if (j+1)-i > 3]
return [i for i in options if len(set(i) & b) == 4 and (set(i) != set(i[:-1]))]
print(get_shortest(s))
输出:
['AAGTC', 'AGTC', 'GTCCTA', 'TCCTAG', 'CCTAG', 'CTAG']
这是您可以使用的另一种方法。也许不像 chrisz answere 那样快速和漂亮。但对于初学者来说可能更容易阅读和理解。
DNA='AAGTCCTAG'
toSave=[]
for i in range(len(DNA)):
letters=['A','G','T','C']
j=i
seq=[]
while len(letters)>0 and j<(len(DNA)):
seq.append(DNA[j])
try:
letters.remove(DNA[j])
except:
pass
j+=1
if len(letters)==0:
toSave.append(seq)
print(toSave)
由于您要查找的子字符串可能具有任意长度,因此后进先出队列似乎可行。一次附加每个字母,检查每个字母是否至少有一个。如果找到return它。然后去掉前面的字母,继续检查,直到不再有效。
def find_agtc_seq(seq_in):
chars = 'AGTC'
cur_str = []
for ch in seq_in:
cur_str.append(ch)
while all(map(cur_str.count,chars)):
yield("".join(cur_str))
cur_str.pop(0)
seq = 'AAGTCCTAG'
for substr in find_agtc_seq(seq):
print(substr)
这似乎会导致您要查找的子字符串:
AAGTC
AGTC
GTCCTA
TCCTAG
CCTAG
CTAG
我真的很想为此创建一个简短的答案,所以这就是我想出的!
s = 'AAGTCCTAG'
d = 'ACGT'
c = len(d)
while c <= len(s):
x,c = s[:c],c+1
if all(l in x for l in d):
print(x)
s,c = s[1:],len(d)
它的工作原理如下:
c
设置为我们确保字符串中存在的字符串的长度(d = ACGT
)
while
循环遍历 s
的每个可能的子字符串,使得 c
小于 s
的长度。
- 这通过在
while
循环的每次迭代中将 c
增加 1 来实现。
- 如果我们的字符串
d
(ACGT
) 中的每个字符都存在于子字符串中,我们打印结果,将 c
重置为其默认值并将字符串切片 1 个字符从头开始。
- 循环继续,直到字符串
s
比 d
短
结果:
AAGTC
AGTC
GTCCTA
TCCTAG
CCTAG
CTAG
改为在列表中获取输出 (see code in use here):
s = 'AAGTCCTAG'
d = 'ACGT'
c,r = len(d),[]
while c <= len(s):
x,c = s[:c],c+1
if all(l in x for l in d):
r.append(x)
s,c = s[1:],len(d)
print(r)
结果:
['AAGTC', 'AGTC', 'GTCCTA', 'TCCTAG', 'CCTAG', 'CTAG']
从任何 *.fasta DNA 序列(仅 'ACTG' 个字符)中,我必须找到每个字母至少包含一次重复的所有序列。
例如从序列 'AAGTCCTAG' 我应该能够找到:'AAGTC'、'AGTC'、'GTCCTA'、'TCCTAG'、'CCTAG'和 'CTAG'(每个字母的迭代)。
我不知道如何在 pyhton 2.7 中做到这一点。我正在尝试使用正则表达式,但它并没有搜索所有变体。
我怎样才能做到这一点?
如果您可以将序列分解成一个列表,例如5 个字母的序列,然后您可以使用此函数查找重复序列。
from itertools import groupby
import numpy as np
def find_repeats(input_list, n_repeats):
flagged_items = []
for item in input_list:
# Create itertools.groupby object
groups = groupby(str(item))
# Create list of tuples: (digit, number of repeats)
result = [(label, sum(1 for _ in group)) for label, group in groups]
# Extract just number of repeats
char_lens = np.array([x[1] for x in result])
# Append to flagged items
if any(char_lens >= n_repeats):
flagged_items.append(item)
# Return flagged items
return flagged_items
#--------------------------------------
test_list = ['aatcg', 'ctagg', 'catcg']
find_repeats(test_list, n_repeats=2) # Returns ['aatcg', 'ctagg']
您可以找到所有长度为 4+ 的子字符串,然后从中向下 select 以仅找到包含每个字母之一的最短可能组合:
s = 'AAGTCCTAG'
def get_shortest(s):
l, b = len(s), set('ATCG')
options = [s[i:j+1] for i in range(l) for j in range(i,l) if (j+1)-i > 3]
return [i for i in options if len(set(i) & b) == 4 and (set(i) != set(i[:-1]))]
print(get_shortest(s))
输出:
['AAGTC', 'AGTC', 'GTCCTA', 'TCCTAG', 'CCTAG', 'CTAG']
这是您可以使用的另一种方法。也许不像 chrisz answere 那样快速和漂亮。但对于初学者来说可能更容易阅读和理解。
DNA='AAGTCCTAG'
toSave=[]
for i in range(len(DNA)):
letters=['A','G','T','C']
j=i
seq=[]
while len(letters)>0 and j<(len(DNA)):
seq.append(DNA[j])
try:
letters.remove(DNA[j])
except:
pass
j+=1
if len(letters)==0:
toSave.append(seq)
print(toSave)
由于您要查找的子字符串可能具有任意长度,因此后进先出队列似乎可行。一次附加每个字母,检查每个字母是否至少有一个。如果找到return它。然后去掉前面的字母,继续检查,直到不再有效。
def find_agtc_seq(seq_in):
chars = 'AGTC'
cur_str = []
for ch in seq_in:
cur_str.append(ch)
while all(map(cur_str.count,chars)):
yield("".join(cur_str))
cur_str.pop(0)
seq = 'AAGTCCTAG'
for substr in find_agtc_seq(seq):
print(substr)
这似乎会导致您要查找的子字符串:
AAGTC
AGTC
GTCCTA
TCCTAG
CCTAG
CTAG
我真的很想为此创建一个简短的答案,所以这就是我想出的!
s = 'AAGTCCTAG'
d = 'ACGT'
c = len(d)
while c <= len(s):
x,c = s[:c],c+1
if all(l in x for l in d):
print(x)
s,c = s[1:],len(d)
它的工作原理如下:
c
设置为我们确保字符串中存在的字符串的长度(d = ACGT
)while
循环遍历s
的每个可能的子字符串,使得c
小于s
的长度。- 这通过在
while
循环的每次迭代中将c
增加 1 来实现。 - 如果我们的字符串
d
(ACGT
) 中的每个字符都存在于子字符串中,我们打印结果,将c
重置为其默认值并将字符串切片 1 个字符从头开始。 - 循环继续,直到字符串
s
比d
短
- 这通过在
结果:
AAGTC
AGTC
GTCCTA
TCCTAG
CCTAG
CTAG
改为在列表中获取输出 (see code in use here):
s = 'AAGTCCTAG'
d = 'ACGT'
c,r = len(d),[]
while c <= len(s):
x,c = s[:c],c+1
if all(l in x for l in d):
r.append(x)
s,c = s[1:],len(d)
print(r)
结果:
['AAGTC', 'AGTC', 'GTCCTA', 'TCCTAG', 'CCTAG', 'CTAG']