寻找优雅的水珠状DNA串扩展

时间:2009-07-08 14:28:03

标签: python permutation glob dna-sequence

我正试图对一组具有多种可能碱基的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

5 个答案:

答案 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序列中寻找它,那么很多更好的方法。)