2016-06-10 106 views
0

所以我在做一个程序,它读取一个文本文件,我需要的所有信息放在各自的变量。它看起来像这样:尝试一个txt文件分割成多个变量

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

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

+0

请检查我的编辑。更大的信号在blockquote解释中迷失了,但是只有你(我们两个)知道哪个输入是在哪一行上。在你的“过去”代码中,“headerline”的内容是“1EK9:...”,对吧?当迭代行时,我不会使用'nucseq + = line.strip('\ n')',这需要经常完成,因为python中的字符串是不可变的,并且这会创建一些工作;-)也许收集剥离的字符串列表(checp)和后处理,然后加入到最后一个字符串中,比如'''.join(the_sequence)' – Dilettant

+1

谢谢!是的,大号只是第一行。因此,代替nucseq + = line.strip('\ n'),你会使用checp?这是做什么的?非常感谢:) – SammieSam

+0

对不起移动设备和手指:这意味着“便宜”,因为在便宜和快速的操作附加到列表。然后你最后用这个联接调用把一个字符串写回你的变量 - 这个联接所有序列元素的字符串就是这里一个空间的方法--HTH和我看到很多已经很好的答案。 – Dilettant

回答

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”下手,你可以尝试用它来提取类似上述使用空间来提取“字”的第一行的方式。

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

最后一行只是那也较早使用的一些操作的结合。

同为B C d等 - 如此大量的手工操作和计算...

要小心A的指标 - 从0开始蟒编号可能无法在你的编号系统的情况。

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

UPDATE2:这也是我不明白什么是空间中的角色 - 到目前为止,我把他们赶走,但在原始字符串计数的字母时,他们可不管。

+0

谢谢!好的解释更好,这部分“A.41,52”告诉我在下面的AAseq感兴趣的位置。这意味着41至52号氨基酸很重要,我需要把它们带出去与他们进一步合作。所以我需要一种方法来保存这些数字,以便我稍后可以说,好的程序从41-52中取出序列并为我做一些工作。现在,对于你的第一位代码,你用空格分割txt文件,对吧?现在只是让他们成为一个列表吗?对于第二位,您正在显示第5项及之后的列表?最后一块,我不明白。再次感谢,这是非常有用的:) – SammieSam

+0

你需要进一步使用'。'分割第一个分割的结果。作为分隔符(例如list.split()[0] .split('。')),然后使用结果列表...然后将这个两级分割列表的元素转换为int(int(list.split ()[0] .split('。'))并使用它们作为索引从第一个分割列表的元素中提取序列....是的,这是一个痛苦,没有真正有效的,很好的方式这样做..一些建议 - 对于这个像这样使用interdictive python - 它是更容易控制结果,因为你的问题是数据的复杂性,而不是代码本身... – VDV

+0

在代码 - 1减少部分 - 只是一个简单的方法来粘住所有的字母序列(从5开始),而不是+多次(+是一个简单的方法来粘合两个列表在一起和字母序列是Python中的列表。在我的prev评论中有代码中的错字 - 应该读取list.split('')[0] .split('。') – VDV

0

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

分裂()允许你指定你所选择的分隔符。如果序列标题(这里是1EK9)始终与冒号的其余部分分开,则可以先通过“:”作为分隔符。然后,您可以使用“;”分割剩余的序列以恢复编号的位置(例如A.41,52)作为分隔符。

我希望这有助于!

+0

感谢您的回应!我的分裂问题是,它是否提供了一个列表?在我看到的例子中,它分裂了['第一件事','第二件事','等等],对吗?那么我可以让这些物品变成自己的变量吗? – SammieSam

+0

是Sammie,list.split()的输出是一个列表!您可以使用[type()](http://www.tutorialspoint.com/python/dictionary_type.htm)方法轻松检查。 – Sheldon

+0

好的,所以我会把variablename.split()?然后我可以抓住这个列表中的部分并制作他们自己的变量,对吧? – SammieSam

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

谢谢!你愿意向我解释这些步骤是做什么的?我很抱歉,这有点超出我的理解。 :) – SammieSam

+0

此外,我已经插入它看看这是什么让我,但我得到的错误“混合迭代和读取方法会失去数据”你知道这意味着什么吗?大声笑我很抱歉我不是很擅长这个:) – SammieSam

0

至于对方的回答可以很好地解决这个假设的问题,在它的全部 - 但OP已请求指针或一个例子tpyical分不分开的变换是通常如此成功,我在此提供一些想法和工作代码来展示这一点(基于问题的例子)。

因此,让我们专注于下面的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)方法仍不清楚,只需询问或尝试对相关问题的优秀答案进行搜索即可。

还要注意,没有必要line.strip('\n')作为\n被认为是空白像' '(字符串只有一个空格)或制表'\t',样品:

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

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

Upate:

的要求,在所谓的问题标题行 “协调部分” 进一步分析:

>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在coordinates.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)} 

在这里,人们可能会这样写明确的一个嵌套的循环,但它是一个迟到的欧洲傍晚所以诀窍是从右阅读:

  1. 为留在het_seq的所有元素
  2. 分割的点和商店a和right in b
  3. 比进一步将bc拆分为k的序列,转换为整数并放入元组(有序对的整数坐标)
  4. 抵达左边你构建一个元组的a尺寸如'A'和从3开始的坐标元组。

在结束通话使用这里的形式字典(key_1,_1,hey_2,_2,...),这也是字典()函数,构造一个字典{key_1:值1,...}

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

I'ld喜欢这里的元组,尽管拆分()生成列表,因为

  1. 你将把这两个坐标不能扩展或追加那双
  2. 在Python中的映射和重映射经常进行有可哈希(即不可变类型)准备成为字典中的关键字。

最后一个变体(无knoted内涵):

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。

+0

谢谢!这真的很有用,它只打印出我的序列。我的下一个问题是如何获得“A.41,52”部分? – SammieSam

+0

等待我想我现在得到它 – SammieSam

+0

这很好 - 没有看到评论,同时键入“答案”的“下一个问题”,也许这有助于我写的 - 将写入一些意见,以最后的unmapping拆分步骤 – Dilettant

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