我想写一个函数,它接受一长串字符(像'UGGUGUUAUUAAUGGUUU'这样的蛋白质序列(,并一次从中提取三个字符(即密码子(。它可以一个接一个地返回每组三个字符,或者一个包含所有三个字符集的列表。无论哪种方式都行得通。但是我在弄清楚如何干净地做到这一点时遇到了一些麻烦。
这是我到目前为止所拥有的:
def get_codon_list(codon_string):
codon_start = 0
codon_length = 3
codon_end = 3
codon_list = []
for x in range(len(codon_string) // codon_length):
codon_list.append(codon_string[codon_start:codon_end])
codon_start += codon_length
codon_end += codon_length
return codon_list
它可以返回密码子列表,但似乎效率很低。如果有更好的方法,我不喜欢使用硬编码的数字和这样的递增变量。我也不喜欢使用 for 循环,实际上并没有在循环中使用变量。这似乎不是对它的正确使用。
关于如何改进这一点的任何建议,无论是使用特定的功能/模块,还是只是更好的 Pythonic 技术?
谢谢!
您可以使用列表推导式,每次从字符串中获取长度为 3 的切片。
>>> s="UGGUGUUAUUAAUGGUUU"
>>> res = [s[i:i+3] for i in range(0,len(s),3)]
>>> res
['UGG', 'UGU', 'UAU', 'UAA', 'UGG', 'UUU']
您可以简单地使用range
函数的step
参数来避免维护变量:
def get_codon_list(codon_string):
codon_length = 3
codon_list = []
for codon_start in range(0, len(codon_string), codon_length):
codon_end = codon_start + codon_length
codon_list.append(codon_string[codon_start:codon_end])
return codon_list
然后它可以成为列表理解:
def get_codon_list(codon_string):
codon_length = 3
codon_list = [codon_string[x:x+codon_length] for x in range(0, len(codon_string), codon_length)]
return codon_list
>itertools
石斑鱼食谱非常适合(https://docs.python.org/3/library/itertools.html#itertools-recipes(:
In [1]: from itertools import zip_longest
In [2]: def grouper(iterable, n, fillvalue=None):
...: "Collect data into fixed-length chunks or blocks"
...: # grouper('ABCDEFG', 3, 'x') --> ABC DEF Gxx"
...: args = [iter(iterable)] * n
...: return zip_longest(*args, fillvalue=fillvalue)
...:
In [3]: list(grouper('UGGUGUUAUUAAUGGUUU', 3))
Out[3]:
[('U', 'G', 'G'),
('U', 'G', 'U'),
('U', 'A', 'U'),
('U', 'A', 'A'),
('U', 'G', 'G'),
('U', 'U', 'U')]
您可能希望在此处使用 while 循环,并在每次迭代时将索引递增 3,打印接下来的三个字母,并在 inedex 在长度的 3 以内退出
使用正则表达式:
import re
def get_codon_list(codon_string):
return list(re.findall(r"(w{3})", codon_string))