将fasta文件格式读入python字典

时间:2015-03-29 18:28:10

标签: python

我有一个格式如下的文件:

>seq1
ATGGGTGTGTGTGTG
>seq2
ATGTGTTTGTGTGCTCCTCCTC
>seq3
AACGTCGTGACGGGTGCGTGGTGTGTGTCCAA

我想在Python中将此文件读作字典。我知道BIO-python函数,但我想学习python中的脚本以及完成我的工作。到目前为止,我已尝试过此代码:

import sys
sequence = ' '
fasta = {}
with open(sys.argv[1]) as file_one:
    file_one_content = file_one.read()
    for line in file_one_content.split("\n"):
        if not line.strip():
            continue
        if line.startswith(">"):
            sequence_name = line.rstrip('\n').replace(">", "")
        else:
            sequence = line.rstrip('\n')
        if sequence_name not in fasta:
            fasta[sequence_name] = []
        fasta[sequence_name].append(sequence)
print fasta

我得到以下输出:

{'seq3': ['ATGTGTTTGTGTGCTCCTCCTC', 'AACGTCGTGACGGGTGCGTGGTGTGTGTCCAA'], 'seq2': ['ATGGGTGTGTGTGTG', 'ATGTGTTTGTGTGCTCCTCCTC'], 'seq1': [' ', 'ATGGGTGTGTGTGTG']}

我的预期输出文件是:

{' seq3':[' AACGTCGTGACGGGTGCGTGGTGTGTGTCCAA'],' seq2':[' ATGTGTTTGTGTGCTCCTCCTC'],' seq1&# 39;:[' ATGGGTGTGTGTGTG']}

我一直试图理解为什么字典以错误的方式打印,但我找不到错误。正如我想要学习的那样,如果你能告诉我如何纠正我的代码中的错误,那就太棒了。感谢。

4 个答案:

答案 0 :(得分:3)

固定。您的if / else逻辑存在问题。

import sys
fasta = {}
with open(sys.argv[1]) as file_one:
    for line in file_one:
        line = line.strip()
        if not line:
            continue
        if line.startswith(">"):
            active_sequence_name = line[1:]
            if active_sequence_name not in fasta:
                fasta[active_sequence_name] = []
            continue
        sequence = line
        fasta[active_sequence_name].append(sequence)

print fasta

<小时/>     python fasta.py input.txt     {'seq3':['AACGTCGTGACGGGTGCGTGGTGTGTGTCCAA'],'seq2'['ATGTGTTTGTGTGCTCCTCCTC'],'seq1':['ATGGGTGTGTGTGTG']}

答案 1 :(得分:2)

由于你的目的是学习Python,我敢于稍微编辑你的代码并稍微解释一下。

import sys
from itertools import imap

fasta = {}
with open(sys.argv[1]) as file_one:
    for line in imap(str.rstrip, file_one):
        if line.startswith(">"):
            sequence_name = line.lstrip(">")
        else:
            fasta.setdefault(sequence_name, []).append(line)

首先,文件对象是迭代器,因此如果您只需要执行一次,则不需要(通过file.read()方法)读取它们。其次,您不需要指定&#34; \ n&#34;在rstrip电话中。此外,您可以使用rstrip(Python 3中的imap)在一个地方懒洋洋地删除所有行,而不是在多个地方调用map。您可以使用dict.setdefault()方法以避免手动密钥检查。

答案 2 :(得分:1)

使用defaultdict使用以>开头的行作为键,然后在文件对象上调用next来获取序列:

from collections import defaultdict

fasta = defaultdict(list)
with open(sys.argv[1]) as file_one:
    for line in file_one:
        if line.startswith(">"):
            fasta[line.strip(">\n")].append(next(file_one).rstrip())
print fasta

defaultdict(<type 'list'>, {'seq1': ['ATGGGTGTGTGTGTG'], 'seq2': ['ATGTGTTTGTGTGCTCCTCCTC'], 'seq3': ['AACGTCGTGACGGGTGCGTGGTGTGTGTCCAA']})

这可以简单地成为一个词典理解:

with open(sys.argv[1]) as file_one:
    fasta = {line.strip(">\n"):next(file_one).rstrip() for line in file_one}
    print(fasta)

除非你有重复的键或空行,否则很多代码都是多余的。

答案 3 :(得分:0)

使用biopython SeqIO和dict理解:

from Bio import SeqIO
seq_dict = {rec.id : rec.seq for rec in SeqIO.parse("myfile.fasta", "fasta")}