尝试将txt文件拆分为多个变量

时间:2016-06-10 17:26:37

标签: python bioinformatics

所以我正在创建一个程序来读取文本文件,我需要将所有信息分成他们自己的变量。它看起来像这样:

>1EK9:A.41,52; B.61,74; C.247,257; D.279,289
ENLMQVYQQARLSNPELRKSAADRDAAFEKINEARSPLLPQLGLGAD
YTYSNGYRDANGINSNATSASLQLTQSIFDMSKWRALTLQEKAAGIQ
DVTYQTDQQTLILNTATAYFNVLNAIDVLSYTQAQKEAIYRQLDQTT
QRFNVGLVAITDVQNARAQYDTVLANEVTARNNLDNAVEQLRQITGN
YYPELAALNVENFKTDKPQPVNALLKEAEKRNLSLLQARLSQDLARE
QIRQAQDGHLPTLDLTASTGISDTSYSGSKTRGAAGTQYDDSNMGQN
KVGLSFSLPIYQGGMVNSQVKQAQYNFVGASEQLESAHRSVVQTVRS
SFNNINASISSINAYKQAVVSAQSSLDAMEAGYSVGTRTIVDVLDAT
TTLYNAKQELANARYNYLINQLNIKSALGTLNEQDLLALNNALSKPV
STNPENVAPQTPEQNAIADGYAPDSPAPVVQQTSARTTTSNGHNPFRN

>之后的代码是一个标题,下一个看起来像这个“A.41,52”的位是我需要保存使用的序列中的编号位置,之后的所有内容都是氨基酸序列。我知道如何处理氨基酸序列,我只需要知道如何分离第一行中的重要数字。

在过去,当我有一个标题和序列时,我做了类似的事情:

for line in nucfile:
if line.startswith(">"):
    headerline=line.strip("\n")[1:]
else:
    nucseq+=line.strip("\n")

我在这里走在正确的轨道上吗?这是我的第一次,任何建议都很棒,感谢阅读:)

5 个答案:

答案 0 :(得分:0)

我不确定我是否完全理解目标(我认为此帖更适合评论,但我没有足够的权限)但我认为解决方案的关键是使用.split()。然后,您可以使用+类似于此来加入结果列表的元素:

>>> result = line.split(' ')
>>> result
['1EK9:A.41,52;', 'B.61,74;', 'C.247,257;', 'D.279,289', 'ENLMQVYQQARLSNPELRKSAADRDAAFEKINEARSPLLPQLGLGAD', 'YTYSNGYRDANGINSNATSASLQLTQSIFDMSKWRALTLQEKAAGIQ', 'DVTYQTDQQTLILNTATAYFNVLNAIDVLSYTQAQKEAIYRQLDQTT', 'QRFNVGLVAITDVQNARAQYDTVLANEVTARNNLDNAVEQLRQITGN', 

'YYPELAALNVENFKTDKPQPVNALLKEAEKRNLSLLQARLSQDLARE', 'QIRQAQDGHLPTLDLTASTGISDTSYSGSKTRGAAGTQYDDSNMGQN', 'KVGLSFSLPIYQGGMVNSQVKQAQYNFVGASEQLESAHRSVVQTVRS', 'SFNNINASISSINAYKQAVVSAQSSLDAMEAGYSVGTRTIVDVLDAT', 'TTLYNAKQELANARYNYLINQLNIKSALGTLNEQDLLALNNALSKPV', 'STNPENVAPQTPEQNAIADGYAPDSPAPVVQQTSARTTTSNGHNPFRN']
    >>> result[3]+result[4]
    'D.279,289ENLMQVYQQARLSNPELRKSAADRDAAFEKINEARSPLLPQLGLGAD'
    >>>

等。您还可以使用通常的以下语法来提取所需列表的元素:

>>> result[5:]
['YTYSNGYRDANGINSNATSASLQLTQSIFDMSKWRALTLQEKAAGIQ', 'DVTYQTDQQTLILNTATAYFNVLNAIDVLSYTQAQKEAIYRQLDQTT', 'QRFNVGLVAITDVQNARAQYDTVLANEVTARNNLDNAVEQLRQITGN', 'YYPELAALNVENFKTDKPQPVNALLKEAEKRNLSLLQARLSQDLARE', 'QIRQAQDGHLPTLDLTASTGISDTSYSGSKTRGAAGTQYDDSNMGQN', 'KVGLSFSLPIYQGGMVNSQVKQAQYNFVGASEQLESAHRSVVQTVRS', 'SFNNINASISSINAYKQAVVSAQSSLDAMEAGYSVGTRTIVDVLDAT', 'TTLYNAKQELANARYNYLINQLNIKSALGTLNEQDLLALNNALSKPV', 'STNPENVAPQTPEQNAIADGYAPDSPAPVVQQTSARTTTSNGHNPFRN']

将他们加在一起:

>>> reduce(lambda x, y: x+y, result[5:])
'YTYSNGYRDANGINSNATSASLQLTQSIFDMSKWRALTLQEKAAGIQDVTYQTDQQTLILNTATAYFNVLNAIDVLSYTQAQKEAIYRQLDQTTQRFNVGLVAITDVQNARAQYDTVLANEVTARNNLDNAVEQLRQITGNYYPELAALNVENFKTDKPQPVNALLKEAEKRNLSLLQARLSQDLAREQIRQAQDGHLPTLDLTASTGISDTSYSGSKTRGAAGTQYDDSNMGQNKVGLSFSLPIYQGGMVNSQVKQAQYNFVGASEQLESAHRSVVQTVRSSFNNINASISSINAYKQAVVSAQSSLDAMEAGYSVGTRTIVDVLDATTTLYNAKQELANARYNYLINQLNIKSALGTLNEQDLLALNNALSKPVSTNPENVAPQTPEQNAIADGYAPDSPAPVVQQTSARTTTSNGHNPFRN'

请记住列表上的+会生成一个列表。

顺便说一下,我不会删除'\ n'开头,因为你可能会尝试使用它来提取类似于上面的第一行,并使用空格来提取“单词”。

更新(从结果开始):

#getting A indexes
letter_seq=result[5:]
ind=result[:4]
Aind=ind[0].split('.')[1].replace(';', '')

#getting one long letter seq
long_letter_seq=reduce(lambda x, y: x+y, letter_seq)

#extracting the final seq fromlong_letter_seq using Aind
output = long_letter_seq[int(Aind.split(',')[0]):int(Aind.split(',')[1])]

最后一行只是之前使用过的几个操作的联合。

同样适用于B C D等 - 因此需要进行大量的手工操作和计算......

小心,索引为A - python中的编号从0开始,编号系统可能不是这种情况。

更优雅的解决方案是使用rehttps://docs.python.org/2/library/re.html)使用掩码查找pettern,但这需要非常明确的规则来查找所需的序列。

UPDATE2:我也不清楚空格的作用是什么 - 到目前为止我删除了它们但是在计算原始字符串中的字母时它们可能很重要。

答案 1 :(得分:0)

我建议您使用split()方法。

split()允许您指定所选的分隔符。如果序列标题(此处为1EK9)始终用冒号与序列的其余部分分开,则可以先将“:”作为分隔符。然后,您可以使用“;”拆分序列的其余部分以恢复编号位置(例如A.41,52)。作为分隔符。

我希望这有帮助!

答案 2 :(得分:0)

我认为您要做的是根据在第一行(以>开头的行)给出的标识符提取序列的某些部分。

此行包含您的标题,然后是序列名称和您需要提取的数据范围。

试试这个:

sequence_pairs = {}

with open('somefile.txt') as f:
   header_line = next(f)
   sequence = f.read()
   title,components = header_line.split(':')
   pairs = components.split(';')
   for pair in pairs:
      start,end = pair[2:-1].split(',')
      sequence_pars[pair[:1]] = sequence[start:int(end)+1]

for sequence,data in sequence_pairs.iteritems():
    print('{} - {}'.format(sequence, data))

答案 3 :(得分:0)

由于另一个答案可能非常好地解决其中的假设问题 - 但是OP已经请求了指针或一个tpyical split-unsplit变换的例子,这通常是如此成功我在此提供一些想法和工作代码来展示这个(基于问题的例子)。

因此,让我们关注下面的else分支:

from __future__ import print_function
nuc_seq = []  # a list
title_token = '>'
with open('some_file_of_a_kind.txt', 'rt') as f:
    for line in f.readlines():
        s_line = line.strip()  # this strips whitespace
        if line.startswith(title_token):
            headerline = line.strip("\n")[1:]
        else:
            nuc_seq.append(s_line)  # build list

# now nuc_seq is a list of strings like:
# ['ENLMQVYQQARLSNPELRKSAADRDAAFEKINEARSPLLPQLGLGAD',  
#  'YTYSNGYRDANGINSNATSASLQLTQSIFDMSKWRALTLQEKAAGIQ',
#  ...
# ]

demo_nuc_str = ''.join(nuc_seq)
# now: 
# demo_nuc_str == 'ENLMQVYQQARLSNPELRKSAADRDAAFEKINEARSPLLPQLGLGADYTYSNGYR ...'

这是Python编程中快速且广泛部署的范例(通常使用强大的数据类型进行编程)。

如果split-unsplit(a.k.a。join)方法仍然不清楚,只需询问或尝试搜索SO以获得相关问题的优秀答案。

另请注意,line.strip('\n')不需要\n被视为空格,如' '(仅限空格的字符串)或制表符'\t',示例:

>>> a = ' \t \n '
>>> '+'.join(a.split())
''

所以"加入角色"只出现,如果至少有两个元素sto连接,在这种情况下,strip删除所有whits空格并留下空字符串。

<强> Upate:

根据要求进一步分析&#34;坐标部分&#34;在称为标题标题的行中:

>1EK9:A.41,52; B.61,74; C.247,257; D.279,289

如果您想要检索:

A.41,52; B.61,74; C.247,257; D.279,289

并假设您(如上面标题字符串中的完整行):

title, coordinate_string = headline.split(':')
# so now title is '1EK9' and
# coordinates == 'A.41,52; B.61,74; C.247,257; D.279,289'

现在拆分半冒号,修剪条目:

het_seq = [z.strip()for coordinates in coordinate.split(&#39 ;;&#39;)]    #now het_seq == [&#39; A.41,52&#39;,&#39; B.61,74&#39;,&#39; C.247,257&#39;,&#39; D. 279289&#39;]

如果&#39;&#39; B&#39;,&#39; C&#39;和&#39; D&#39;是众所周知的尺寸,而不是你可以&#34;失去&#34;来自输入文件的订购信息(因为你可以随时强化你已经知道的东西;-)并可能将协调点映射为键:(有序坐标对):

>>> coord_map = dict(
        (a, tuple(int(k) for k in bc.split(','))) 
         for a, bc in (abc.split('.') for abc in het_seq))
>>> coord_map
{'A': (41, 52), 'C': (247, 257), 'B': (61, 74), 'D': (279, 289)}

在微观计划的背景下:

#! /usr/bin/enc python
from __future__ import print_function

het_seq = ['A.41,52', 'B.61,74', 'C.247,257', 'D.279,289']

coord_map = dict(
    (a, tuple(int(k) for k in bc.split(',')))
    for a, bc in (abc.split('.') for abc in het_seq))
print(coord_map)

的产率:

{'A': (41, 52), 'C': (247, 257), 'B': (61, 74), 'D': (279, 289)}

这里有人可能会把这个显式写成一个嵌套的for循环,但这是一个欧洲晚会,所以诀窍是从右边读取它:

  1. 表示het_seq的所有元素
  2. 在点上分割并在左侧和右侧存储在
  3. 进一步将bc拆分为k序列,转换为整数并放入元组(有序整数坐标对)
  4. 到达左边,你建立了一个a元组(&#34;维度类似于&#39; A&#39;和#3的坐标元组。
  5. 最后调用dict()函数构造一个字典,在这里使用表单dict(key_1,value_1,hey_2,value_2,...)给出{key_1:value1,...}

    因此所有坐标都是整数,存储有序对作为元组。

    我更喜欢这里的元组,虽然split()会生成列表,因为

    1. 您将保持这两个坐标不会延伸或附加该对
    2. 在python映射和重新映射中经常执行,并且可以使用hashable(即不可变类型)成为dict中的键。
    3. 最后一个变体(没有结合的理解):

      coord_map = {}
      for abc in het_seq:
          a, bc = abc.split('.')
          coord_map[a] = tuple(int(k) for k in bc.split(','))
      print(coord_map)
      

      前四行产生与上述轻微令人讨厌的相同&#34;一个衬垫&#34; (已经写在括号内的三行上。)

      HTH。

答案 4 :(得分:0)

所以我假设你正在尝试处理类似Fasta的文件,所以我这样做的方法是首先获取标题并用Regex分隔各个部分。之后,您可以将A:42.52 B ...存储在列表中以便于访问。代码如下。

import re

def processHeader(line):
     positions = re.search(r':(.*)', line).group(1)
     positions = positions.split('; ')
     return positions

dnaSeq = ''
positions = []
with open('myFasta', 'r') as infile:
     for line in infile:
          if '>' in line:
              positions = processHeader(line)
          else:
              dnaSeq += line.strip()