无法在python中解析此文件

时间:2016-01-05 19:18:19

标签: python parsing

我正在python中解析像这样的文件: 1bgxt是蛋白质,序列和二级结构,phi角度是信息的类型,序列是我想要在具有核心蛋白的列表中的信息。 关于蛋白质的信息是交替的这一事实导致我一些麻烦。 文件例子(它可以有2个以上的蛋白质和2个以上的序列信息):

P1;1bgxt
sequence
MRGMLPLFEPKGRVLLVDGHHLAYRTFHALKGLTTSRGEPVQAVYGFAKSLLKALKEDGDAVIVVFDAKAPSFRH*
P1;1xo1a
sequence
----------RRNLMIVDGTNLGFRFP--------------FASSYVSTIQSLAKSYSARTTIVLGDKG-KSVFR*
P1;1bgxt
secondary structure and phi angle
CPPCCCPPPCPCPCCCCCCCCHHHHCCCCPCCCCCCCPCCCCCCCCHHHHHHHHHHCPCCCCCCCCCCCCCCCCC*
P1;1xo1a
secondary structure and phi angle
----------CCEEEEEEHHHHHCCCC--------------CHHHHHHHHHHHHHHCPEEEEEEECCCP-CCHHH*

等等更多序列。

我想存储这样的信息:

list = [
    ["1bgxt",
     "MRGMLPLFEPKGRVLLVDGHHLAYRTFHALKGLTTSRGEPVQAVYGFAKSLLKALKEDGDAVIVVFDAKAPSFRH*",
     CPPCCCPPPCPCPCCCCCCCCHHHHCCCCPCCCCCCCPCCCCCCCCHHHHHHHHHHCPCCCCCCCCCCCCCCCCC*],
    ["1xo1a",
     "----------RRNLMIVDGTNLGFRFP--------------FASSYVSTIQSLAKSYSARTTIVLGDKG-KSVFR*",
     "----------CCEEEEEEHHHHHCCCC--------------CHHHHHHHHHHHHHHCPEEEEEEECCCP-CCHHH*"]
]

我非常感谢您提供的任何帮助。

1 个答案:

答案 0 :(得分:0)

假设您有一个遵循这种粗略结构的文件:

P1;1bgxt
sequence
MRGMLPLFEPKGRVLLVDGHHLAYRTFHALKGLTTSRGEPVQAVYGFAKSLLKALKEDGDAVIVVFDAKAPSFRH*
P1;1xo1a
sequence
----------RRNLMIVDGTNLGFRFP--------------FASSYVSTIQSLAKSYSARTTIVLGDKG-KSVFR*
P1;1bgxt
secondary structure and phi angle
CPPCCCPPPCPCPCCCCCCCCHHHHCCCCPCCCCCCCPCCCCCCCCHHHHHHHHHHCPCCCCCCCCCCCCCCCCC*
P1;1xo1a
secondary structure and phi angle
----------CCEEEEEEHHHHHCCCC--------------CHHHHHHHHHHHHHHCPEEEEEEECCCP-CCHHH*

'''解析这个文件的原因是你可以一次只读取3行的文件,因为文件的结构很容易分解为重复循环:

Protein Name
Data Descriptor
Data

由于您在评论中提到的内容,我正在制作这些基本假设

  • 数据描述符序列或与结构相关的内容
  • 所有蛋白质都有序列和某种结构
  • 所有序列数据都来自结构数据
  • 行数不能被6整除的文件是坏文件(因为总共需要6行代表每种蛋白质)

解析为dict

首先,我要说原始帖子中你想要的结构可能不是解析数据的最佳选择,而且你的数据整齐地适合像dict这样的关联数据结构。 / p>

假设您有一个名为sequences.txt的上述文件:

from itertools import izip_longest
import pprint

# This is adapted from [itertools recipes](https://docs.python.org/2/library/itertools.html#recipes)
def grouper(iterable, n, fillvalue=None):
    args = [iter(iterable)] * n
    return izip_longest(*args, fillvalue=fillvalue)

proteins = {}
with open('sequences.txt') as datafile:

    # The following line reads the file as groups of 3 lines
    # I do this rather than read the entire file in one go because
    # you might have a lot of data in a file
    line_groups = grouper(datafile, 3)

    for block in line_groups:
        # I am adding variables here to make it clearer
        protein_name = block[0].strip()
        descriptor = block[1].strip()
        data = block[2].strip()

        if descriptor.lower() == 'sequence':
            # sequence is found, that means we haven't
            # seen this protein yet
            proteins[protein_name] = [protein_name, data]
        else:
            # This is some type of structure data, so just append to what
            # we've already seen
            try:
                protein = proteins[protein_name]
                protein.append(data)
            except KeyError:
                # Wait, how did we see a structure before a sequence?
                # This file is invalid

                raise # Or handle it however you want - exit, or discard data, etc.

pprint.pprint(proteins)

这将输出如下结构:

{'P1;1bgxt': ['P1;1bgxt',
              'MRGMLPLFEPKGRVLLVDGHHLAYRTFHALKGLTTSRGEPVQAVYGFAKSLLKALKEDGDAVIVVFDAKAPSFRH*',
              'CPPCCCPPPCPCPCCCCCCCCHHHHCCCCPCCCCCCCPCCCCCCCCHHHHHHHHHHCPCCCCCCCCCCCCCCCCC*'],
 'P1;1xo1a': ['P1;1xo1a',
              '----------RRNLMIVDGTNLGFRFP--------------FASSYVSTIQSLAKSYSARTTIVLGDKG-KSVFR*',
              '----------CCEEEEEEHHHHHCCCC--------------CHHHHHHHHHHHHHHCPEEEEEEECCCP-CCHHH*']}

如果您想获取列表列表,可以在.values()上致电proteins

>> proteins.values()

[['P1;1bgxt',
  'MRGMLPLFEPKGRVLLVDGHHLAYRTFHALKGLTTSRGEPVQAVYGFAKSLLKALKEDGDAVIVVFDAKAPSFRH*',
  'CPPCCCPPPCPCPCCCCCCCCHHHHCCCCPCCCCCCCPCCCCCCCCHHHHHHHHHHCPCCCCCCCCCCCCCCCCC*'],
 ['P1;1xo1a',
  '----------RRNLMIVDGTNLGFRFP--------------FASSYVSTIQSLAKSYSARTTIVLGDKG-KSVFR*',
  '----------CCEEEEEEHHHHHCCCC--------------CHHHHHHHHHHHHHHCPEEEEEEECCCP-CCHHH*']]

直接解析list list

如果您不想在最后一段代码中使用dict,那么这涉及到一些不同的工作,但您只需更改几行。

请注意,给定足够大的数据集,此版本可能会花费更多时间,因为实际上,每当您需要找到预先存在的蛋白质以将结构数据添加到现有子列表时,它将扫描列表( O(n)操作),而在字典中,蛋白质数据的查找通常是O(1)。虽然对你有用的东西可能会有所不同,这取决于你使用的数据,但我离题了。

from itertools import izip_longest
import pprint

# This is adapted from [itertools recipes](https://docs.python.org/2/library/itertools.html#recipes)
def grouper(iterable, n, fillvalue=None):
    args = [iter(iterable)] * n
    return izip_longest(*args, fillvalue=fillvalue)

proteins = []
with open('sequences.txt') as datafile:

    # The following line reads the file as groups of 3 lines
    # I do this rather than read the entire file in one go because
    # you might have a lot of data in a file
    line_groups = grouper(datafile, 3)

    for block in line_groups:
        # I am adding variables here to make it clearer
        protein_name = block[0].strip()
        descriptor = block[1].strip()
        data = block[2].strip()

        if descriptor.lower() == 'sequence':
            # sequence is found, that means we haven't
            # seen this protein yet
            proteins.append([protein_name, data])
        else:
            # This is some type of structure data, so just append to what
            # we've already seen

            # find the item in the list that contains this protein
            try:
                protein = next(x for x in proteins if x[0] == protein_name)
                protein.append(data)
            except StopIteration:
                # Hm, we couldn't find a sublist that has this protein name
                raise

pprint.pprint(proteins)

这将输出:

>> pprint.pprint(proteins)
[['P1;1bgxt',
  'MRGMLPLFEPKGRVLLVDGHHLAYRTFHALKGLTTSRGEPVQAVYGFAKSLLKALKEDGDAVIVVFDAKAPSFRH*',
  'CPPCCCPPPCPCPCCCCCCCCHHHHCCCCPCCCCCCCPCCCCCCCCHHHHHHHHHHCPCCCCCCCCCCCCCCCCC*'],
 ['P1;1xo1a',
  '----------RRNLMIVDGTNLGFRFP--------------FASSYVSTIQSLAKSYSARTTIVLGDKG-KSVFR*',
  '----------CCEEEEEEHHHHHCCCC--------------CHHHHHHHHHHHHHHCPEEEEEEECCCP-CCHHH*']]

请注意,我没有做任何严格的错误检查,而且为了清晰起见,我尝试使用比惯用代码更多的示范代码。我也没有尝试过使用像类这样的东西存储数据,或使用元组或namedtuple存储所有相关数据,因为这需要对文件进行更多的预处理以获得最小的收益。有用性(元组在Python中是不可变的,所以我不能只修改一个元组而不只是创建一个元组。)