Python 中的生物信息学:我的代码是否有更简洁的方法?有很多 "if" 和 "for" 语句
Bioinformatics in Python: Is there a less lengthy approach to my code? Has a lot of "if" and "for" statements
def prot_from_rf(aa_seq):
prot1 = []
global proteins
for aa in aa_seq:
if aa == "_":
if prot1:
for p in prot1:
proteins.append(p)
prot1 = []
else:
if aa == "M":
prot1.append("")
for i in range(len(prot1)):
prot1[i] += aa
return proteins
Input:
MNQT_CLI_VVQLSPHLYRWISTCVNASSRRRPKRKIPCTQSPRELYTD
Output:
MNQT
此代码的目标是扫描氨基酸序列并将起始密码子和结束密码子之间生成的蛋白质附加到列表(蛋白质)中。 Prot1 是一个临时列表,未处理的氨基酸序列从这里开始。想知道是否有更短的方法来完成同样的事情。
对于不熟悉生物学的人来说,我取了一长串字母,如果有 "M" 它开始累积字符直到到达“_”,然后停止并添加这个列表(全局蛋白质)的新字符串不包括“_”字符。
您可以排除一些内容:
1) 您不需要将 proteins
声明为全局。您只是追加而不是重新分配,因此只要它在此函数的外部范围内声明,它将在您的函数内可用。
2) 你不需要检查 prot1
是否为空,因为空数组上的 for 循环没有效果。
3) 这个循环可以缩短:
for p in prot1:
proteins.append(p)
相当于:
proteins.extend(prot1)
这会将您的代码缩减为:
def prot_from_rf(aa_seq):
prot1 = []
for aa in aa_seq:
if aa == "_":
proteins.extend(prot1)
prot1 = []
else:
if aa == "M":
prot1.append("")
for i in range(len(prot1)):
prot1[i] += aa
return proteins
正如其他人评论的那样,在此处使用 global
关键字不是好的做法。相反,将 proteins
列表保留在其中,并将其扩展到函数之外。
我也会避免单个字符的连接,但只收集 "M" 的偏移量,并在到达终止“_”后使用它们对字符串进行切片。
这是它的样子:
def prot_from_rf(aa_seq):
result = []
starts = []
for i, ch in enumerate(aa_seq):
if ch == "_":
result.extend([aa_seq[m:i] for m in starts])
starts = []
elif ch == "M":
starts.append(i)
return result
呼叫为:
proteins = []
# ...
proteins.extend(prot_from_rf("NMNQT_CLI_VVMQLSMPHLYR_WISTCVNAMSS"))
print(proteins)
上一个回答
之前我仍然不清楚您的代码是否真的正确处理了在出现“_”之前有多个 "M" 个字符的情况。
如果预期的行为是第二个 "M" 实际上结束一个序列(如果一个序列正在进行)并立即开始下一个序列,那么您可以使用正则表达式。
import re
def prot_from_rf(aa_seq):
return re.findall(r"M[^M_]*", aa_seq)
# Example use:
proteins = []
# ...
proteins.extend(prot_from_rf("MNQT_CLI_VVQLSPHLYRWISTCVNASSRRRPKRKIPCTQSPRELYTD"))
print(proteins)
def prot_from_rf(aa_seq):
prot1 = []
global proteins
for aa in aa_seq:
if aa == "_":
if prot1:
for p in prot1:
proteins.append(p)
prot1 = []
else:
if aa == "M":
prot1.append("")
for i in range(len(prot1)):
prot1[i] += aa
return proteins
Input:
MNQT_CLI_VVQLSPHLYRWISTCVNASSRRRPKRKIPCTQSPRELYTD
Output:
MNQT
此代码的目标是扫描氨基酸序列并将起始密码子和结束密码子之间生成的蛋白质附加到列表(蛋白质)中。 Prot1 是一个临时列表,未处理的氨基酸序列从这里开始。想知道是否有更短的方法来完成同样的事情。
对于不熟悉生物学的人来说,我取了一长串字母,如果有 "M" 它开始累积字符直到到达“_”,然后停止并添加这个列表(全局蛋白质)的新字符串不包括“_”字符。
您可以排除一些内容:
1) 您不需要将 proteins
声明为全局。您只是追加而不是重新分配,因此只要它在此函数的外部范围内声明,它将在您的函数内可用。
2) 你不需要检查 prot1
是否为空,因为空数组上的 for 循环没有效果。
3) 这个循环可以缩短:
for p in prot1:
proteins.append(p)
相当于:
proteins.extend(prot1)
这会将您的代码缩减为:
def prot_from_rf(aa_seq):
prot1 = []
for aa in aa_seq:
if aa == "_":
proteins.extend(prot1)
prot1 = []
else:
if aa == "M":
prot1.append("")
for i in range(len(prot1)):
prot1[i] += aa
return proteins
正如其他人评论的那样,在此处使用 global
关键字不是好的做法。相反,将 proteins
列表保留在其中,并将其扩展到函数之外。
我也会避免单个字符的连接,但只收集 "M" 的偏移量,并在到达终止“_”后使用它们对字符串进行切片。
这是它的样子:
def prot_from_rf(aa_seq):
result = []
starts = []
for i, ch in enumerate(aa_seq):
if ch == "_":
result.extend([aa_seq[m:i] for m in starts])
starts = []
elif ch == "M":
starts.append(i)
return result
呼叫为:
proteins = []
# ...
proteins.extend(prot_from_rf("NMNQT_CLI_VVMQLSMPHLYR_WISTCVNAMSS"))
print(proteins)
上一个回答
之前我仍然不清楚您的代码是否真的正确处理了在出现“_”之前有多个 "M" 个字符的情况。
如果预期的行为是第二个 "M" 实际上结束一个序列(如果一个序列正在进行)并立即开始下一个序列,那么您可以使用正则表达式。
import re
def prot_from_rf(aa_seq):
return re.findall(r"M[^M_]*", aa_seq)
# Example use:
proteins = []
# ...
proteins.extend(prot_from_rf("MNQT_CLI_VVQLSPHLYRWISTCVNASSRRRPKRKIPCTQSPRELYTD"))
print(proteins)