繁体   English   中英

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

[英]Trying to split a txt file into multiple variables

因此,我正在编写一个程序,在该程序中读取文本文件,并且需要将所有信息分成各自的变量。 看起来像这样:

>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")

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

我不确定我是否完全理解目标(我认为这篇文章更适合发表评论,但我没有足够的特权),但是我认为解决方案的关键是使用.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”开头,因为您可能会尝试使用它来提取与上面类似的第一行,并使用空格来提取“单词”。

UPDATE(从结果开始):

#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])]

最后一行只是先前也使用过的几个操作的结合。

与BCD等相同-因此需要大量的人工工作和计算...

请务必使用A的索引-python中的编号从0开始,在您的编号系统中可能不是这种情况。

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

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

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

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

我希望这有帮助!

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

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

尝试这个:

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))

由于另一个答案可能会很好地解决整个假设的问题-但OP已要求提供指针或典型的拆分-未拆分转换的示例,该转换通常非常成功,因此我在此提供一些想法和工作代码来说明这一点(基于问题的示例)。

因此,让我们关注下面的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编程(以及通常具有强大数据类型的编程)中快速且广泛部署的范例。

如果仍然不清楚拆分未拆分(也称为联接)方法,请询问或尝试对相关问题的最佳答案进行搜索。

还要注意,不需要line.strip('\\n')因为\\n被视为空白,例如' ' (仅带空格的字符串)或制表符'\\t' ,例如:

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

因此,如果至少有两个要连接的元素,则仅出现“连接字符”,在这种情况下,strip删除了所有白色空间,并给我们留下了空字符串。

更新:

根据要求,在题为标题的行中进一步分析“坐标部分”:

>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(),z中的axis.split(';')]#现在het_seq == ['A.41,52','B.61,74','C.247,257','D .279,289']

如果'a','B','C'和'D'是众所周知的尺寸,那么您可以从输入文件中“丢失”订购信息(因为您总是可以加强已经知道的内容;-)并可以映射坐标为键:(有序坐标对):

>>> 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. 在点上分割并在a和b中向左存储
  3. 然后将bc进一步分成k的序列,转换为整数并放入元组(整数坐标的有序对)
  4. 到达左侧,您将构建a的元组(“像'A'的维和从3开始的坐标元组。

最后,调用dict()函数,该函数使用dict(key_1,value_1,hey_2,value_2,...)形式构造字典,该字典给出{key_1:value1,...}

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

我在这里更喜欢元组,尽管split()会生成列表,因为

  1. 您将保持这两个坐标不延伸或追加该对
  2. 在python中,通常执行映射和重新映射,并且有一个哈希(即不可变类型)准备好成为字典中的键。

最后一个变体(无打结的理解):

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)

前四行产生的效果与上述轻微的令人讨厌的“一个衬里”(已经写在括号内的三行上)相同。

HTH。

因此,我假设您正在尝试处理类似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()

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM