我正试图对一组具有多种可能碱基的DNA串进行类似全球扩展。
我的DNA字符串的基数包含字母A,C,G和T.但是,我可以使用像M这样的特殊字符,可以是A或C.
例如,假设我有字符串:
ATMM
我想将此字符串作为输入并输出四个可能的匹配字符串:
ATAA
ATAC
ATCA
ATCC
我觉得必须有一些优雅的Python / Perl / Regular Expression技巧才能做到这一点。
感谢您的任何建议。
编辑,感谢产品运营商的cortex。这是我的解决方案:
仍然是一个Python新手,所以我敢打赌,有一个更好的方法来处理每个字典键而不是另一个字典键。任何建议都会很棒。
import sys
from itertools import product
baseDict = dict(M=['A','C'],R=['A','G'],W=['A','T'],S=['C','G'],
Y=['C','T'],K=['G','T'],V=['A','C','G'],
H=['A','C','T'],D=['A','G','T'],B=['C','G','T'])
def glob(str):
strings = [str]
## this loop visits very possible base in the dictionary
## probably a cleaner way to do it
for base in baseDict:
oldstrings = strings
strings = []
for string in oldstrings:
strings += map("".join,product(*[baseDict[base] if x == base
else [x] for x in string]))
return strings
for line in sys.stdin.readlines():
line = line.rstrip('\n')
permutations = glob(line)
for x in permutations:
print x
答案 0 :(得分:2)
同意其他海报,想要这样做似乎很奇怪。当然,如果你真的想要,有(一如既往)优雅的方式在Python(2.6 +)中做到这一点:
from itertools import product
map("".join, product(*[['A', 'C'] if x == "M" else [x] for x in "GMTTMCA"]))
输入处理的完整解决方案:
import sys
from itertools import product
base_globs = {"M":['A','C'], "R":['A','G'], "W":['A','T'],
"S":['C','G'], "Y":['C','T'], "K":['G','T'],
"V":['A','C','G'], "H":['A','C','T'],
"D":['A','G','T'], "B":['C','G','T'],
}
def base_glob(glob_sequence):
production_sequence = [base_globs.get(base, [base]) for base in glob_sequence]
return map("".join, product(*production_sequence))
for line in sys.stdin.readlines():
productions = base_glob(line.strip())
print "\n".join(productions)
答案 1 :(得分:1)
您可能可以使用yield运算符
在python中执行类似的操作def glob(str):
if str=='':
yield ''
return
if str[0]!='M':
for tail in glob(str[1:]):
yield str[0] + tail
else:
for c in ['A','G','C','T']:
for tail in glob(str[1:]):
yield c + tail
return
编辑:正确地指出我犯了一些错误。这是我试用过的版本。
答案 2 :(得分:0)
这实际上并不是一个“扩展”问题,而且几乎肯定不能用任何明智的正则表达式来实现。
我相信你所寻找的是“如何产生排列”。
答案 3 :(得分:0)
例如,你可以递归地执行此操作。伪代码:
printSequences(sequence s)
switch "first special character in sequence"
case ...
case M:
s1 = s, but first M replaced with A
printSequences(s1)
s2 = s, but first M replaced with C
printSequences(s2)
case none:
print s;
答案 4 :(得分:0)
Regexps 匹配字符串,它们并不打算转换为可能匹配的每个字符串。
此外,您正在查看从此处输出的大量字符串 - 例如:
MMMMMMMMMMMMMMMM (16 M's)
产生65,536个16个字符串 - 我猜测DNA序列通常比那个长。
可以说,从计算机科学的角度来看,任何解决方案都是“暴力”,因为你的算法在原始字符串长度上是O(2 ^ n)。实际上还有很多工作要做。
为什么要制作所有组合?你打算怎么处理他们? (如果你想要产生每一个字符串的可能性,然后在一个大的DNA序列中寻找它,那么很多更好的方法。)