我想为一系列突变的 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 突变。我也不确定如何将字典与此联系起来。有人可以告诉我更好的方法吗?谢谢。
最佳答案
听起来您的问题有两个部分。第一个是您想要对 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% 的长度为 4 的字符串根本没有发生突变)。较长的字符串会更频繁地发生突变,并且您更有可能在一个字符串中看到多个突变。
关于python - 随机 DNA 突变发生器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24050294/