2015-03-29 4 views
2

У меня есть файл в следующем формате:Чтение Fasta формат файла в 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 ': [' ATGGGTGTGTGTGTG ']}

Я пытался понять, почему словарь напечатан неправильно, но я не могу найти ошибку. Как я хочу узнать, было бы здорово, если бы вы могли сообщить мне, как я могу исправить ошибку в своем коде. Благодарю.

+2

Ваш ожидаемый результат? –

+0

Пожалуйста, покажите нам фактический файл ввода и ожидаемый результат для этого входного файла. –

ответ

2

Исправлено. Была проблема с вашей логикой 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

Используйте defaultdict с использованием линий, которые начинаются с > как ключи и словом следующего объекта файла, чтобы получить последовательность:

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) 

Если вы не повторяете ключи или пустые строки, ваш код будет лишним.

+0

Спасибо за ваш комментарий. Это не тот порядок, который имеет значение, и я не понимаю, почему пары ключей и значений не распечатываются правильно. То есть я хочу, чтобы каждый ключ (seq1, seq2 и seq3) получил только одно значение (ближайшая строка после них) в качестве значений. – Homap

+0

@ user1945881, я только что видел ваше редактирование, я делаю ответ –

+0

Отлично, такая короткая форма кода, спасибо! – Homap

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()), если вам нужно только сделать это один раз. Во-вторых, вам не нужно указывать «\ n» в вызове rstrip. Кроме того, вместо звонка rstrip в нескольких местах, вы можете использовать imap (map в Python 3), чтобы лениво разделить все линии в одном месте. И вы можете просто использовать метод dict.setdefault(), чтобы избежать ручной проверки ключа.

+0

Большое спасибо. Я собираюсь определенно использовать 'dict.setdefault()' отныне, очень полезную точку. – Homap

0

Использование biopython SeqIO и Dict понимания:

from Bio import SeqIO 
seq_dict = {rec.id : rec.seq for rec in SeqIO.parse("myfile.fasta", "fasta")} 
Смежные вопросы