定义一个返回不同可能性的循环

H.F*_* C. 0 python loops function

您好我是python的新手.我有以下问题:我想写一个脚本,给定带有歧义的(dna)序列,写入所有可能的序列,(如果少于100,如果有超过100个可能的序列,则适当的错误消息是印刷品)对于DNA核苷酸含糊不清:http://www.bioinformatics.org/sms/iupac.html

示例:对于“AYGH”脚本输出的序列“ACGA”, “ACGC”, “ACGT”, “ATGA”, “ATGC”,和“ATGT”.A,C,G和T是默认核苷酸.所有其他人可以有不同的值(见链接).

所以我写了这个:

def possible_sequences (seq):
    poss_seq = ''
    for i in seq:
        if i=='A'or i=='C'or i=='G'or i=='T': 
            poss_seq += i 
        else: 
            if i== 'R':  
                poss_seq += 'A' # OR 'G', how should i implement this? 
            elif i == 'Y': 
                poss_seq += 'C' # OR T 
            elif i == 'S': 
                poss_seq += 'G' # OR C
            elif i == 'W': 
                poss_seq += 'A' # OR T 
            elif i == 'K': 
                poss_seq += 'G' # OR T
            elif i == 'M': 
                poss_seq += 'A' # OR C
            elif i == 'B': 
                poss_seq += 'C' # OR G OR T 
            elif i == 'D': 
                poss_seq += 'A' # OR G OR T 
            elif i == 'H': 
                poss_seq += 'A' # OR C OR T 
            elif i == 'V': 
                poss_seq += 'A' # OR C OR G 
            elif i == 'N': 
                poss_seq += 'A' # OR C OR G OR T 
            elif i == '-' or i == '.': 
                poss_seq += ' '
    return poss_seq
Run Code Online (Sandbox Code Playgroud)

当我测试我的功能:possible_sequences('ATRY-C')我得到了:

'ATAC C'
Run Code Online (Sandbox Code Playgroud)

但我应该得到:

'ATAC C'
'ATAT C' 
'ATGC C'
'ATGT C'
Run Code Online (Sandbox Code Playgroud)

有人能帮帮我吗?我明白,当存在歧义但我不知道如何......时,我必须回顾并写下第二个poss_seq.

nie*_*mmi 7

您可以itertools.product用来生成可能性:

from itertools import product

# List possible nucleotides for each possible item in sequence
MAP = {
    'A': 'A',
    'C': 'C',
    'G': 'G',
    'T': 'T',
    'R': 'AG',
    'Y': 'CT',
    'S': 'GC',
    'W': 'AT',
    'K': 'GT',
    'M': 'AC',
    'B': 'CGT',
    'D': 'AGT',
    'H': 'ACT',
    'V': 'ACG',
    'N': 'ACGT',
    '-': ' ',
    '.': ' '
}

def possible_sequences(seq):
    return (''.join(c) for c in product(*(MAP[c] for c in seq)))

print(list(possible_sequences('AYGH')))
print(list(possible_sequences('ATRY-C')))
Run Code Online (Sandbox Code Playgroud)

输出:

['ACGA', 'ACGC', 'ACGT', 'ATGA', 'ATGC', 'ATGT']
['ATAC C', 'ATAT C', 'ATGC C', 'ATGT C']
Run Code Online (Sandbox Code Playgroud)

在上面我们首先迭代给定序列中的项目并获得每个项目的可能核苷酸列表:

possibilities = [MAP[c] for c in 'ATRY-C']
print(possibilities)

# ['A', 'T', 'AG', 'CT', ' ', 'C']
Run Code Online (Sandbox Code Playgroud)

然后将iterable作为参数解压缩,product返回笛卡尔积:

products = list(product(*['A', 'T', 'AG', 'CT', ' ', 'C']))
print(products)

# [('A', 'T', 'A', 'C', ' ', 'C'), ('A', 'T', 'A', 'T', ' ', 'C'), 
#  ('A', 'T', 'G', 'C', ' ', 'C'), ('A', 'T', 'G', 'T', ' ', 'C')]
Run Code Online (Sandbox Code Playgroud)

最后,每个产品都转为一个字符串join:

print(list(''.join(p) for p in products))

# ['ATAC C', 'ATAT C', 'ATGC C', 'ATGT C']
Run Code Online (Sandbox Code Playgroud)

请注意,possible_sequences返回生成器而不是一次构造所有可能的序列,因此您可以随时轻松地停止迭代,而不必等待生成每个序列.