随机DNA突变发生器

时间:2014-06-05 01:42:38

标签: python python-3.x bioinformatics

我想为一系列突变的DNA链创建一个字典字典,每个字典都展示了它的原始基础以及它变异的基础。

详细说明,我想做的是创建一个生成器,允许人们输入一个特定的DNA链,并让它产生100个随机生成的链,其突变频率为0.66%(这适用于每个碱基,并且每个基地都可以变异到任何其他基地)。然后,我想要做的是创建一系列字典,其中每个字典详细说明在特定随机生成的链中发生的突变。我希望关键是原始基础,并且值是新的变异基础。有这么简单的方法吗?到目前为止,我一直在试验一个如下所示的循环:

#yields a strand with an A-T mutation frequency of 0.066%
def mutate(string, mutation, threshold):
    dna = list(string)
    for index, char in enumerate(dna):
        if char in mutation:
            if random.random() < threshold:
                dna[index] = mutation[char]

    return ''.join(dna)

dna = "ATGTCGTACGTTTGACGTAGAG"
print("DNA first:", dna)
newDNA = mutate(dna, {"A": "T"}, 0.0066)
print("DNA now:", newDNA)

但是我只能用这个代码产生一条链,它只关注T - > A突变。我也不确定如何将字典与此联系起来。有人能告诉我一个更好的方法吗?感谢。

1 个答案:

答案 0 :(得分:2)

听起来你的问题有两个部分。第一个是你想要多次改变你的DNA序列,第二个是你想收集一些关于某种数据结构中突变的额外信息。我将分别处理每一个。

从相同的源字符串生成100个随机结果非常简单。您可以使用显式循环(例如,在生成器函数中),但您可以轻松地使用列表推导来反复运行单突变函数:

results = [mutate(original_string) for _ in range(100)]

当然,如果使mutate函数更复杂,这个简单的代码可能不合适。如果它返回某种更复杂的数据结构,而不仅仅是一个字符串,您可能需要进行一些额外的处理,以便以您想要的格式组合数据。

至于如何构建这些数据结构,我认为你已经拥有的代码是一个良好的开端。您需要确定您将如何访问您的数据,然后让它指导您使用正确的容器。

例如,如果您只想简单记录字符串中发生的所有突变,我建议一个基本列表,其中包含突变之前和之后的基本元组。另一方面,如果您希望能够有效地查找给定基础变异的内容,则将列表作为值的字典可能更合适。如果您愿意,还可以包括变异基数的索引。

这是对函数的快速尝试,该函数返回变异字符串以及记录所有突变的元组列表:

bases = "ACGT"

def mutate(orig_string, mutation_rate=0.0066):
    result = []
    mutations = []
    for base in orig_string:
        if random.random() < mutation_rate:
            new_base = bases[bases.index(base) - random.randint(1, 3)] # negatives are OK
            result.append(new_base)
            mutations.append((base, new_base))
        else:
            result.append(base)
    return "".join(result), mutations

这段代码中最棘手的一点是我如何选择替换当前的基础。表达式bases[bases.index(base) - random.randint(1, 3)]一次完成所有操作。让我们分解不同的位。 bases.index(base)在代码顶部的全局bases字符串中给出了前一个基数的索引。然后我从该索引(random.randint(1, 3))中减去一个随机偏移量。新索引可能是否定的,但是没关系,因为当我们使用它索引回bases字符串(bases[...])时,负索引从右边开始计数,而不是从左边开始。

以下是您可以使用它的方法:

string = "ATGT"
results = [mutate(string) for _ in range(100)]
for result_string, mutations in results:
    if mutations: # skip writing out unmutated strings
        print(result_string, mutations)

对于短字符串,例如"ATGT",您不太可能获得多个突变,甚至一个非常罕见。上面的循环往往在每次运行时打印2到4个结果(也就是说,超过95%的长度 - 四个字符串根本没有变异)。较长的字符串会更频繁地发生突变,而且你会在一个字符串中看到多个突变更为合理。