生成随机的DNA序列

6
我将尝试使用随机数和随机字符串在Python中生成DNA的随机序列。但是我只得到一个字符串作为输出。例如:如果我给出长度为5的DNA(String(5)),那么我应该得到输出“CTGAT”。同样,如果我给出String(4),它应该给我“CTGT”。但我得到“G”或“C”或“T”或“A”,即每次只有单个字符串。请问有谁可以帮助我吗?
我尝试了以下代码:
from random import choice
def String(length):

   DNA=""
   for count in range(length):
      DNA+=choice("CGTA")
      return DNA
5个回答

10

我会一次性生成整个字符串,而不是逐步构建。除非Python很聪明并且优化了字符串相加,否则它将把运行时复杂度从二次降低到线性。

import random

def DNA(length):
    return ''.join(random.choice('CGTA') for _ in xrange(length))

print DNA(5)

谁投了反对票应该留个注释(比如“这个问题是关于理解代码块和缩进的”)。使用 str.join() 比逐个添加字母(DNA碱基)要快得多。 - lgautier
你可以将每个碱基的频率放在代码中,而不是使用random.choice('CGTA')这样的随机选择方法。例如:random.choice("A"*5+"C"*4+"G"*3+"T"*10)。请用实际相对数量替换我给出的数字。 - Stefan Gruenwald

7

您返回的过快:

from random import choice
def String(length):

   DNA=""
   for count in range(length):
      DNA+=choice("CGTA")
      return DNA

如果你的return语句在for循环内部,那么你只会迭代一次——你将会通过return退出函数。

来自Python文档有关return语句的说明: "return离开当前的函数调用并以表达式列表(或None)作为返回值。"
所以,请将return放在函数的末尾。
def String(length):

       DNA=""
       for count in range(length):
          DNA+=choice("CGTA")
       return DNA

编辑:这里有一个加权选择的方法(目前仅适用于字符串,因为它使用字符串重复)。

def weightedchoice(items): # this doesn't require the numbers to add up to 100
    return choice("".join(x * y for x, y in items))

然后,在循环中你需要调用weightedchoice而不是choice

DNA += weightedchoice([("C", 10), ("G", 20), ("A", 40), ("T", 30)])


非常感谢。现在它可以工作了。我能添加一个分布吗?例如,String(10,[(“a”,20),(“b”,60),(“c”,20)]),其中概率总和为100(20 + 60 + 20)。 - Rachel

1
也许是因为向量化,NumPy 的工作速度更快?
import numpy as np
seq_length = 100
my_seq = ''.join(np.random.choice(('C','G','T','A'), seq_length ))

0

我已经升级了代码,以提供从0到100%的GC百分比分布。上面的代码始终产生50%的分布。

actg_distribution字符串可以是已知GC百分比的现有DNA序列的任意长度。某个范围内的GC百分比是常见的用例。


import random

# Return random CGTA sequences, set minimum = maximum to get a specified length.
def random_length_dnasequence(minimum=25, maximum=10000, actg_distribution=None):
    if (minimum == maximum):
        length = minimum
    else:
        length = random.randint(minimum, maximum)
    if (actg_distribution == None):
        actg_distribution = ''.join(random.choice('cgta') for _x in xrange(7))

    return ''.join(random.choice(actg_distribution) for _x in xrange(length))


def random_dnasequence(length, actg_distribution=None):
    return random_length_dnasequence(length, length, actg_distribution)

0

使用random.choices的Python 3.6快速函数

import random

def string(length=int(), letters="CGTA"):
        #slower 0.05s for 20000 nt
#     dna =""
#     for count in range(length):
#         dna+=choice("CGTA")
#     return dna

    #0.013s for 20000 nt
    return''.join(random.choices(letters, k=length)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接