如何使用Python对列表中的两个元素(序列)进行对齐和比较

0 投票
2 回答
1770 浏览
提问于 2025-04-18 12:32

这是我的问题:

我有一个文件,内容大概是这样的:

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 个回答

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变量。

0

你可以把这个过程分成三个不同的部分:

  1. 解析输入数据;
  2. 构建新的无序字符串;
  3. 输出新的文件。

第(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

撰写回答