如何使用Python对列表中的两个元素(序列)进行对齐和比较
这是我的问题:
我有一个文件,内容大概是这样的:
103L 序列: MNIFEMLRIDEGLRLKIYKDTEGYYTIGIGHLLTKSPSLNSLDAAKSELDKAIGRNTNGVITKDEAEKLFNQDVDAAVRGILRNAKLKPVYDSLDAVRRAALINMVFQMGETGVAGFTNSLRMLQQKRWDEAAVNLAKSRWYNQTPNRAKRVITTFRTGTWDAYKNL 无序区: ----------------------------------XXXXXX-----------------------------------------------------------------------------------------------------------------------------XX
这个文件包含了名字,这里是103L;还有蛋白质序列,前面有“序列:”的标签;接下来是无序区域,前面有“无序区:”。其中,“-”表示这个位置是有序的,而“X”表示这个位置是无序的。比如,最后两个“XX”表示蛋白质序列的最后两个位置是无序的,也就是“NL”。在我使用分割方法后,内容变成了这样:
['>103L', '序列:', 'MNIFEMLRIDEGLRLKIYKDTEGYYTIGIGHLLTKSPSLNSLDAAKSELDKAIGRNTNGVITKDEAEKLFNQDVDAAVRGILRNAKLKPVYDSLDAVRRAALINMVFQMGETGVAGFTNSLRMLQQKRWDEAAVNLAKSRWYNQTPNRAKRVITTFRTGTWDAYKNL', '无序区:', '----------------------------------XXXXXX-----------------------------------------------------------------------------------------------------------------------------XX']
我想用Python来找到无序序列及其位置。所以最终的文件应该看起来像这样:
名字 序列: '真实序列'
无序区: 位置(Posi) 残基名(R)
以103L为例:
103L 序列: MNIFEMLRIDEGLRLKIYKDTEGYYTIGIGHLLTKSPSLNSLDAAKSELDKAIGRNTNGVITKDEAEKLFNQDVDAAVRGILRNAKLKPVYDSLDAVRRAALINMVFQMGETGVAGFTNSLRMLQQKRWDEAAVNLAKSRWYNQTPNRAKRVITTFRTGTWDAYKNL
无序区: Posi R
34 K
35 S
36 P
37 S
38 L
39 N
65 N
66 L
我刚开始学Python,真的希望有人能帮我,非常感谢!!!
2 个回答
假设我们有一个变量,里面存放着split命令的结果。
split_list = ['>103L', 'Sequence:', 'MNIFEMLRIDEGLRLKIYKDTEGYYTIGIGHLLTKSPSLNSLDAAKSELDKAIGRNTNGVITKDEAEKLFNQDVDAAVRGILRNAKLKPVYDSLDAVRRAALINMVFQMGETGVAGFTNSLRMLQQKRWDEAAVNLAKSRWYNQTPNRAKRVITTFRTGTWDAYKNL', 'Disorder:', '----------------------------------XXXXXX-----------------------------------------------------------------------------------------------------------------------------XX']
我们只关注重要的部分,也就是第2项和第4项。
res_name = split_list[2] # ( i.e. 'MNIFEML...' )
disorder = split_list[4] # ( i.e. '-----...XXX')
你可以这样把两个数组的元素关联起来。
sets = []
for i,c in enumerate( disorder ):
if c == 'X':
sets.append( (i, res_name[i]) )
在Python中,enumerate命令可以遍历一个像列表的对象,并为每个成员返回一个索引和一个项目(i,c)。在这个操作结束时,sets将包含我们想要的元组,分别是'X'在disorder中出现的索引号和对应的res_name中的残基。
sets = [(34,'K'), (35,'S') ... ]
如果你想用Python的另一个好功能,可以用一种叫做列表推导式在一行内构建集合。
sets = [ (i,res_name[i]) for i,c in enumerate(disorder) if c=='X' ]
这是一种快速构建列表的方法,比起循环会更高效,尽管对于你示例中的大约100个项目来说,差别不大。接下来要做的就是把这些新数据写入文件。我们可以通过创建另一个列表,并用空格把各个部分连接起来,来生成你想要的格式的字符串。对于列表中的每个元组,我们想要索引的字符串版本和残基名称(它已经是字符串了)。这可以这样完成:
txt = ' '.join( [str(t[0]) + ' ' + t[1] for t in sets] )
变量txt现在将等于
>>> txt
'34 K 35 S 36 P 37 S 38 L 39 N 165 N 166 L'
要按照你指定的格式写入文件,可以这样做:
f = open( 'test.out', 'w' )
f.write( ' '.join(split_list[0:2]) + '\n' )
f.write( split_list[2] + ' Disorder: Posi R ' + txt )
f.close()
第一个写入命令会在第一行放上'>103L Sequence:'并添加一个换行符。第二个命令则输出原始的残基序列和我们上面创建的txt变量。
你可以把这个过程分成三个不同的部分:
- 解析输入数据;
- 构建新的无序字符串;
- 输出新的文件。
第(1)和第(3)部分比较简单,所以我会重点讲讲第(2)部分。你需要做的主要事情是遍历你的“无序字符串”,在这个过程中你可以访问每个位置的字符,以及这个位置本身。实现这个的一个方法是使用 enumerate
:
for i, x in enumerate(S)
这会给你一个 生成器,它会为字符串 S
中的每个位置(存储在 i
中)和字符(存储在 x
中)提供数据。一旦你得到了这个,你需要做的就是在 seq
中记录位置和字符,每当无序字符串中出现 "X"
的时候。在Python中,这可能看起来像这样:
if (x == 'X'):
new_disorder.append( "{} {}".format(i, seq[i]) )
在这里,我们把结果格式化为一个字符串,比如 "34 R"。
下面是一个完整的例子:
# Parse the file which was already split into split_list
split_list = ['>103L', 'Sequence:', 'MNIFEMLRIDEGLRLKIYKDTEGYYTIGIGHLLTKSPSLNSLDAAKSELDKAIGRNTNGVITKDEAEKLFNQDVDAAVRGILRNAKLKPVYDSLDAVRRAALINMVFQMGETGVAGFTNSLRMLQQKRWDEAAVNLAKSRWYNQTPNRAKRVITTFRTGTWDAYKNL', 'Disorder:', '----------------------------------XXXXXX-----------------------------------------------------------------------------------------------------------------------------XX']
header = split_list[0] + " " + split_list[1]
seq = split_list[2]
disorder = split_list[4]
# Create the new disorder string
new_disorder = ["Disorder: Posi R"]
for i, x in enumerate(disorder):
if x == "X":
# Appends of the form: "AminoAcid Position"
new_disorder.append( "{} {}".format(i, seq[i]) )
new_disorder = " ".join(new_disorder)
# Output the modified file
open("seq2.txt", "w").write( "\n".join([header, seq, new_disorder]))
注意,我得到的输出和你给出的例子稍微有点不同:
103L Sequence:
MNIFEMLRIDEGLRLKIYKDTEGYYTIGIGHLLTKSPSLNSLDAAKSELDKAIGRNTNGVITKDEAEKLFNQDVDAAVRGILRNAKLKPVYDSLDAVRRAALINMVFQMGETGVAGFTNSLRMLQQKRWDEAAVNLAKSRWYNQTPNRAKRVITTFRTGTWDAYKNL
Disorder: Posi R 34 K 35 S 36 P 37 S 38 L 39 N 165 N 166 L