【问题标题】:Parse fasta sequence to the dictionary将 fasta 序列解析为字典
【发布时间】:2014-05-07 02:05:24
【问题描述】:

我需要最简单的解决方案来转换包含多个核苷酸序列的 fasta.txt,例如

>seq1
TAGATTCTGAGTTATCTCTTGCATTAGCAGGTCATCCTGGTCAAACCGCTACTGTTCCGG
CTTTCTGATAATTGATAGCATACGCTGCGAACCCACGGAAGGGGGTCGAGGACAGTGGTG
>seq2
TCCCTCTAGAGGCTCTTTACCGTGATGCTACATCTTACAGGTATTTCTGAGGCTCTTTCA
AACAGGTGCGCGTGAACAACAACCCACGGCAAACGAGTACAGTGTGTACGCCTGAGAGTA
>seq3
GGTTCCGCTCTAAGCCTCTAACTCCCGCACAGGGAAGAGATGTCGATTAACTTGCGCCCA
TAGAGCTCTGCGCGTGCGTCGAAGGCTCTTTTCGCGATATCTGTGTGGTCTCACTTTGGT

到字典(名称,值)对象,其中名称将是>标题,值将分配给相应的序列。

您可以在下面找到我失败的尝试,通过 2 个列表进行操作(不适用于包含 >1 行的长序列)

f = open('input2.txt', 'r')
list={}
names=[]
seq=[]
for line in f:
 if line.startswith('>'):
  names.append(line[1:-1])
 elif line.startswith('A') or line.startswith('C') or line.startswith('G') or line.startswith('T'):
  seq.append(line)

list = dict(zip(names, seq))

如果您向我提供如何修复它的解决方案并举例说明如何通过单独的函数进行修复,我将不胜感激。

感谢您的帮助,

格莱布

【问题讨论】:

    标签: python dictionary fasta


    【解决方案1】:

    对您的代码进行简单的更正:

    from collections import defaultdict #this will make your life simpler
    f = open('input2.txt','r')
    list=defaultdict(str)
    name = ''
    for line in f:
        #if your line starts with a > then it is the name of the following sequence
        if line.startswith('>'):
            name = line[1:-1]
            continue #this means skips to the next line
        #This code is only executed if it is a sequence of bases and not a name.
        list[name]+=line.strip()
    

    更新:

    由于我收到通知说这个旧答案被赞成,我决定展示我现在认为是使用 Python 3.7 的正确解决方案。翻译到 Python 2.7 只需要删除输入导入行和函数注释:

    from collections import OrderedDict
    from typing import Dict
    
    NAME_SYMBOL = '>'
    
    
    def parse_sequences(filename: str,
                        ordered: bool=False) -> Dict[str, str]:
        """
        Parses a text file of genome sequences into a dictionary.
        Arguments:
          filename: str - The name of the file containing the genome info.
          ordered: bool - Set this to True if you want the result to be ordered.
        """
        result = OrderedDict() if ordered else {}
    
        last_name = None
        with open(filename) as sequences:
            for line in sequences:
                if line.startswith(NAME_SYMBOL):
                    last_name = line[1:-1]
                    result[last_name] = []
                else:
                    result[last_name].append(line[:-1])
    
        for name in result:
            result[name] = ''.join(result[name])
    
        return result
    

    现在,我意识到 OP 要求“最简单的解决方案”,但是由于他们正在处理基因组数据,因此假设每个序列可能非常大似乎是公平的。在这种情况下,通过将序列行收集到一个列表中进行一些优化是有意义的,然后在最后对这些列表使用str.join 方法以产生最终结果。

    【讨论】:

    • 非常感谢您的建议。您还可以为我提供带有列表实例的使用 defaultdict 的示例(以将名称和序列保存在字典之外的单独列表中)。最好的,格列布
    • 我知道这已经过时了,但我刚刚收到通知说这个答案已被投票,所以我会回复您的评论 @user3470313 。字典可以通过.keys() 方法为您提供其中的键列表。如果您需要键保持有序,您可以使用集合模块中的 OrderedDict 类,但是您必须在循环中添加几行簿记。我会更新我的答案来证明这一点。
    【解决方案2】:

    最好用biopython库

    from Bio import SeqIO
    input_file = open("input.fasta")
    my_dict = SeqIO.to_dict(SeqIO.parse(input_file, "fasta"))
    

    【讨论】:

      猜你喜欢
      • 2022-08-24
      • 2018-02-11
      • 1970-01-01
      • 1970-01-01
      • 2018-03-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-11-04
      相关资源
      最近更新 更多