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

2024-09-27 07:18:43 发布

您现在位置:Python中文网/ 问答频道 /正文

所以,这个程序运行得很好,但是即使在合并了abarner建议的最后一个修改之后,它仍然不能确保产生一个独特的突变。在

这就是我目前所掌握的。我确信这是不对的,但我不完全理解python是如何执行abarner下面编写的代码的。在

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]

我也尝试过不使用range来编写这个程序,虽然我喜欢使用range函数,这样我可以打印出10或100个密码子,并手动检查输出是否正确,但是后来我得到了一个键错误:“r”,在尝试确保每个替换都是唯一的之前运行此程序时没有发生过:

^{pr2}$

Tags: toinfordatastringindexlinerange
1条回答
网友
1楼 · 发布于 2024-09-27 07:18:43

函数^{}从序列中选取一个随机元素。所以:

letter_to_replace = random.choice(['A', 'C', 'G', 'T'])

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

^{pr2}$

除了如果每个codon都是一个字符串,当然,您不能对其进行适当的变异,所以您需要这样一个函数:

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

我们在这里要做的是用片段构建一个新的字符串:s[:index]是从开始到第index的所有字符(记住Python切片是半开的:s[i:j]包括ii+1j-1,但不是{}),而{}是从index+1到结尾的所有字符。所以,这是index之前的所有内容,char代替了index中的所有内容,然后是{}之后的所有内容。本教程的Strings部分对此进行了详细描述(在同一章的列表部分有一些后续内容)。在

当你已经做了不变的事情:

codons = [string_replace(codon, random.randrange(3), letter_to_replace)
          for codon in codons]

这使用了一个列表理解:我们构建了一个新的密码子列表,而不是适当地修改密码子列表。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

您还可以在使用if子句构建列表时对其进行筛选,将多个for子句嵌套在一起,生成一个set或{},或者一个延迟生成器,而不是list有关详细信息,请参见the documentation。在


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

# 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]

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

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]

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

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

new_base = random.choice([base for base in codon if base != codon[index]])

相关问题 更多 >

    热门问题