我想输入一个DNA序列,并生成某种生成器,以产生具有一定突变频率的序列。例如,假设我具有DNA链“ ATGTCGTCACACACCGCAGATCCGTGTTTGAC”,并且我想创建T-> A频率为5%的突变。我将如何创建它?我知道可以使用以下代码来创建随机突变:
import random
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)
但是我真的不确定怎么做是确定一个固定的突变频率。有人知道该怎么做吗?谢谢。
编辑:
如果我使用字节数组,那么格式应该像这样,因为出现错误:
import random
dna = "ATGTCGTACGTTTGACGTAGAG"
def mutate(dna, mutation, threshold):
dna = bytearray(dna) #if you don't want to modify the original
for index in range(len(dna)):
if dna[index] in mutation and random.random() < threshold:
dna[index] = mutation[char]
return dna
mutate(dna,{“ A”:“ T”},0.05)print(“ my dna now:”,dna)
错误:“ TypeError:不带编码的字符串参数”
编辑2:
import random
myDNA = bytearray("ATGTCGTCACACACCGCAGATCCGTGTTTGAC")
def mutate(dna, mutation, threshold):
dna = myDNA # if you don't want to modify the original
for index in range(len(dna)):
if dna[index] in mutation and random.random() < threshold:
dna[index] = mutation[char]
return dna
mutate(dna, {"A": "T"}, 0.05)
print("my dna now:", dna)
产生错误
您问我一个有关打印所有可能突变的函数的信息,就是这样。输出的数量随输入数据的长度呈指数增长,因此该功能仅打印可能性,而不会以某种方式存储它们(这会消耗大量内存)。我创建了一个递归函数,此函数不应与非常大的输入一起使用,我还将添加一个非递归函数,该函数应无问题或无限制地工作。
def print_all_possibilities(dna, mutations, index = 0, print = print):
if index < 0: return #invalid value for index
while index < len(dna):
if chr(dna[index]) in mutations:
print_all_possibilities(dna, mutations, index + 1)
dnaCopy = bytearray(dna)
dnaCopy[index] = ord(mutations[chr(dna[index])])
print_all_possibilities(dnaCopy, mutations, index + 1)
return
index += 1
print(dna.decode("ascii"))
# for testing
print_all_possibilities(bytearray(b"AAAATTTT"), {"A": "T"})
这在python 3上对我有效,如果您愿意,我也可以解释代码。
注意:此功能需要一个字节数组,如功能测试中所给。
说明:
此函数在dna中搜索可能发生突变的位置,该位置从索引开始,因此通常从0开始,一直到结束。这就是while循环(每次循环执行时都会增加索引)用于的原因(它基本上是正常的迭代,如for循环)。如果该函数找到了可能发生突变的地方(if chr(dna[index]) in mutations:
),则它将复制dna并让第二个突变(dnaCopy[index] = ord(mutations[chr(dna[index])])
,请注意,字节数组是一个数值数组,因此我一直使用chr和ord来在字符串和整数)。之后,再次调用该函数以查找更多可能的突变,因此该函数再次在两个可能的dna中寻找可能的突变,但是它们跳过了已经扫描的点,因此它们从index + 1
。之后,将打印顺序传递给调用的函数print_all_possibilities,因此我们不再需要执行任何操作并使用退出执行return
。如果我们再也找不到任何突变,我们将打印可能的dna,因为我们不会再次调用该函数,所以没有其他人会这样做。
听起来可能很复杂,但这或多或少是一种优雅的解决方案。另外,要了解递归,您必须了解递归,因此,如果您暂时不了解递归,请不要打扰自己。如果您在一张纸上进行尝试,这可能会有所帮助:取一个简单的dna字符串“ TTATTATTA”,其可能的突变为“ A”->“ T”(因此我们有8个可能的突变),然后执行以下操作:遍历该字符串从左到右,如果找到一个可以改变序列的位置(这里只是“ A”的位置),请再次写下该字符串,这次让字符串在给定位置发生突变,这样您的第二个字符串与原始字符串略有不同。在原件和副本中,标记出您走了多远(也许在“ |”后面 在您让其变异的字母之后),然后将副本作为新的原件重复此过程。如果找不到任何可能的突变,请在字符串下划线(这等同于打印它)。最后,您应该有8个不同的字符串都带有下划线。我希望这可以帮助您理解它。
编辑:这是非递归函数:
def print_all_possibilities(dna, mutations, printings = -1, print = print):
mut_possible = []
for index in range(len(dna)):
if chr(dna[index]) in mutations: mut_possible.append(index)
if printings < 0: printings = 1 << len(mut_possible)
for number in range(min(printings, 1 << len(mut_possible)):
dnaCopy = bytearray(dna) # don't change the original
counter = 0
while number:
if number & (1 << counter):
index = mut_possible[counter]
dnaCopy[index] = ord(mutations[chr(dna[index])])
number &= ~(1 << counter)
counter += 1
print(dnaCopy.decode("ascii"))
# for testing
print_all_possibilities(bytearray(b"AAAATTTT"), {"A": "T"})
该功能带有附加参数,可以控制最大输出数量,例如
print_all_possibilities(bytearray(b"AAAATTTT"), {"A": "T"}, 5)
只会打印5条结果。
说明:
如果您的dna有x个可能突变的位置,则您有2 ^ x个可能的突变,因为dna在每个位置都可以突变或不突变。此函数查找dna可以突变的所有位置并将其存储在其中mut_possible
(这是for循环的代码)。现在mut_possible
包含dna可以突变的所有位置,因此我们有2个^ len(mut_possible)
(len(mut_possible)
是mut_possible中元素的数量)可能的突变。我写过1 << len(mut_possible)
,是一样的,但是速度更快。如果printings
为负数,该功能将决定打印所有可能性并将打印设置为可能的数目。如果打印结果是肯定的,但低于可能性的数量,则该功能将仅打印printings
突变,因为min(printings, 1 << len(mut_possible))
将返回较小的数字,即printings
。否则,该功能将打印出所有可能性。现在我们必须number
经历range(...)
,因此该循环(每次打印一个突变)将执行所需的次数。而且,数字每次都会增加一。(例如,range(4)类似于[0,1,2,3])。接下来,我们使用数字创建一个突变。要了解此步骤,您必须了解一个二进制数。如果我们的数字为10,则为二进制1010。这些数字告诉我们必须在哪里修改dna(dnaCopy
)代码。第一位为0,因此我们不修改可能发生突变的第一个位置,第二位为1,因此我们修改此位置,之后为0,依此类推。 “我们使用变量位counter
。number & (1 << counter)
如果counter
设置了第th位,它将返回非零值,因此,如果设置了该位,我们将在counter
可能发生突变的第th位置修改dna 。这是用mut_possible编写的,因此我们的期望位置是mut_possible[counter]
。在该位置上对dna进行突变后,我们将该位设置为0,以表明我们已经修改了该位置。这是用完成的number &= ~(1 << counter)
。之后,我们增加计数器以查看其他位。while循环仅在number不为0时才继续执行,因此如果number设置了至少一位(如果我们必须修改dna的至少一个位置)。修改dnaCopy之后,while循环完成,然后打印结果。
我希望这些解释可以有所帮助。我发现您是python的新手,请花些时间让它沉入其中,如果还有其他问题,请与我联系。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句