如何从选项列表中选择一个随机值并在另一个列表中替换该值?详情如下:

bio*_*mer 0 python random replace

因此,该程序运行良好,但即使合并了 abarnert 建议的最后修改后,它仍然无法确保生成唯一的突变。

这是我到目前为止所得到的。我确定是不对的,但是我并不完全理解python是如何执行下面abarnert编写的代码的。

a = open (scgenome, 'r')

codon = [ ] 

for line in a:

    data=line.split("\t") 

    codon.append(data[12]) 

import random 

def string_replace(s,index,char):
    return s[:index] + char + s[index+1:]


for x in range(1,1000):
   index = random.randrange(3)
   letter_to_replace = random.choice(list({"A", "G", "T", "C"} - {codon[index]}))
   mutated_codon = [string_replace(codon[x], index, letter_to_replace)]
       for c in mutated_codon: 
             codon_lookup[c]
Run Code Online (Sandbox Code Playgroud)

我也尝试在不使用范围的情况下以您的方式编写此代码,尽管我喜欢使用范围函数以便我可以打印出 10 或 100 个密码子并手动检查输出是否正确,但随后我得到了一个 Keyerror: 'r',在尝试确保每个替换都是唯一的之前,当我运行这个程序时没有发生过:

def string_replace(s,index,char):

    return s[:index] + char + s[index+1:]



def mutate_codon(codon):

  index = random.randrange(3)

  letter_to_replace = random.choice(list({"A", "G", "T", "C"} - {codon[index]}))

  return string_replace(codon, index, letter_to_replace)



 for codon in codons:
   codons = mutate_codon(codon)

   print codons 

   for c in codons:

      codon_lookup[c]

      if codon_lookup[c] == ref_aminoacid[x]:

           print codons, "\t", codon_lookup[c]

      else: 

          print codons, "\t", codon_lookup[c]
Run Code Online (Sandbox Code Playgroud)

aba*_*ert 5

该函数random.choice从序列中选择一个随机元素。所以:

letter_to_replace = random.choice(['A', 'C', 'G', 'T'])
Run Code Online (Sandbox Code Playgroud)

要从给定的密码子中选择一个字母,您真的想随机选择一个索引- 0、1 或 2。(毕竟,对于密码子'AAA',您大概希望能够替换三个'A'字符中的任何一个,对吗? ) 为此,请使用random.randrange(3)

for codon in codons:
    index_to_replace = random.randrange(3)
    codon[index_to_replace] = letter_to_replace
Run Code Online (Sandbox Code Playgroud)

除了如果 eachcodon是一个字符串,当然,你不能就地改变它,所以你需要一个像这样的函数:

def string_replace(s, index, char):
    return s[:index] + char + s[index+1:]
Run Code Online (Sandbox Code Playgroud)

我们在这里做的是用切片构建一个新字符串:s[:index]是从开始到第indexth 的所有字符(记住 Python 切片是半开的:s[i:j]包括i, i+1, ..., j-1, 但不是j),并且s[index+1]是所有的从index+1th 到结尾的字符。所以,这是之前的一切indexchar代替了之前的一切index,然后是之后的一切index。这在教程的字符串部分有详细描述(在同一章的列表部分有一些后续)。

虽然你已经在做一成不变的事情:

codons = [string_replace(codon, random.randrange(3), letter_to_replace)
          for codon in codons]
Run Code Online (Sandbox Code Playgroud)

这使用了列表理解:我们没有修改就地密码子列表,而是构建一个新的密码子列表。本教程中的List Comprehensions解释了这些是如何工作的,但一个简单的例子可能会有所帮助:

a = [1, 2, 3, 4]
b = [2 * element for element in a]
assert b == [2, 4, 6, 8]

c = []
for element in a:
    c.append(2 * element)
assert c == b
Run Code Online (Sandbox Code Playgroud)

您还可以在使用if子句构建列表时过滤列表,将多个for子句嵌套在一起,构建一个setordict或一个惰性生成器,而不是一个list......有关完整详细信息,请参阅文档


以下是如何将它们放在一起,以及其他一些修复(使用 awith确保文件被关闭,以及我对这个问题发表的一些评论):

# Read the codons into a list
with open(scgenome) as f:
    codons = [line.split('\t')[12] for line in f]

# Create a new list of mutated codons
def string_replace(s, index, char):
    return s[:index] + char + s[index+1:]
letter_to_replace = random.choice(['A', 'C', 'G', 'T'])
codons = [string_replace(codon, random.randrange(3), letter_to_replace)
          for codon in codons]
Run Code Online (Sandbox Code Playgroud)

如果您想保证每个密码子中的单点突变,并且不需要每个密码子都突变到相同的碱基,则需要重新考虑一下。对于每个密码子,选择三个位置之一。然后,不是从所有四个基地中随机挑选,而是从所有基地中挑选,除了已经存在的基地。所以:

def string_replace(s, index, char):
    return s[:index] + char + s[index+1:]

def mutate_codon(codon):
    index = random.randrange(3)        
    new_base = random.choice(list({'A', 'C', 'T', 'G'} - {codon[index]}))
    return string_replace(codon, index, new_base)

codons = [mutate_codon(codon) for codon in codons]
Run Code Online (Sandbox Code Playgroud)

如果该函数行令人困惑,让我解释一下:集合有一个很好的-运算符来计算集合差——也就是说,左边集合中的所有值都不在右边集合中。{'A', 'C', 'T', 'G'} - {'T'}{'A', 'C', 'G'}。所以,我取所有四个碱基的集合,减去已经在 的那个codon[index],然后随机选择其他三个中的任何一个。由于choice仅适用于序列,因此我必须从集合中列出一个列表。

当然,您可以首先重写它以使用列表(甚至 str),但是您必须手动编写“列表差异”。没什么大不了的:

new_base = random.choice([base for base in codon if base != codon[index]])
Run Code Online (Sandbox Code Playgroud)