當前位置:
首頁 > 知識 > Python如何解析fasta格式,並儲存為字典?

Python如何解析fasta格式,並儲存為字典?

今天想到一個問題:

我如何把fasta文件讀到Python裡面,存為字典格式。

由於技術不過關,我折騰了半天還不知道如何做。所以就去Google,很多人提議用biopython。但是讀取序列其實是一件比較基礎的能力,而且任務也比較簡單, 用基礎庫的話比較通用,也能鍛煉自己的編程能力。

最後發現有一個人在stackoverflow提問,為何他寫的代碼結果不是預期那樣:

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

if not line.strip():

continue

if line.startswith(">"):

sequence_name = line.rstrip("
").replace(">", "")

else:

sequence = line.rstrip("
")

if sequence_name not in fasta:

fasta[sequence_name] = []

fasta[sequence_name].append(sequence)

print fasta

結果如下:

{"seq3": ["ATGTGTTTGTGTGCTCCTCCTC", "AACGTCGTGACGGGTGCGTGGTGTGTGTCCAA"], "seq2": ["ATGGGTGTGTGTGTG", "ATGTGTTTGTGTGCTCCTCCTC"],

"seq1": [" ", "ATGGGTGTGTGTGTG"]}

代碼存在問題,但是和我想要的結果類似,所以改改錯誤就行了,首先知道他到底錯在哪裡,先看看提問者的思路:

代碼逐行解釋

import sys

: 導入sys, 通過sys.argv讀取命令行參數

fasta = {}

:定義了一個字典,fasta用於存放數據。

sequence = " "

: 定義了一個含有一個空格的字元串,,sequene用於存放序列

with open(sys.argv[1]) as file_one:

:利用sys.args[1]讀取文件,然後用open打開,成為python里的file object,用於IO操作。

file_one_content = file_one.read():

就是把所有文件讀到了一個字元串里。

for line in file_one_content.split("
"):

根據換行符進行分割

第一個條件語句主要用於剔除空白行

if not line.strip():

continue

第二個條件語句,提問者的目的是對每一行進行分類,如果以」>」開頭當作序列名,否則就是序列。

if line.startswith(">"):

sequence_name = line.rstrip("
").replace(">", "")

else:

sequence = line.rstrip("
")

第三個條件語句, 提問者的意圖是判斷序列是不是在字典中,去重

if sequence_name not in fasta:

fasta[sequence_name] = []

fasta[sequence_name].append(sequence)

: 由於同一個基因序列是可以是多行存放的,所以需要追加在後面。

尋找真兇

那麼問題來了,道理是哪裡出錯了?

以下列序列為例,對代碼進行演示:

ATGGGTGTGTGTGTG

ATGTGTTTGTGTGCTCCTCCTC

AACGTCGTGACGGGTGCGTGGTGTGTGTCCAA

由於非空,跳過第一個條件語句。因為以」>」開始,那麼

sequence_name

就是seq1.因為seq1不在字典中,所以內容為空,並且append了一個空字元串。因此可以解釋為什麼seq1裡面有一個是空的。

ATGGGTGTGTGTGTG

過來的時候,不是」>」開頭,那麼就是序列了,填入到了seq1字典的值中。

由於非空,所以是序列名,添加到字典中,然後

fasta[sequence_name].append(sequence)

, 就會插入剛才的

ATGGGTGTGTGTGTG

。接著添加了自身的

ATGTGTTTGTGTGCTCCTCCTC

所以錯誤就是,字典賦值不應該直接放在循壞中,應該放在條件語句中。

正確的代碼

知道代碼,錯在哪裡之後,就可以根據這個邏輯寫出正確的代碼。由於file object已經時可迭代對象,不需要用file.read()一次性讀取所有字元然後分割,也不需要用file.readlines()讀取每一行。

優化後的代碼如下:

import sys

fasta = {}

seq_name = ""

sequence = ""

for line in os.open(sys.argv[1]):

if not line.strip():

continue

if line.startswith(">"):

seq_name = line

else:

sequence = line

if seq_name not in fasta:

fasta[seq_name] = []

continue

fasta[seq_name] = sequence

測試下效果:

test = """

ATGGGTGTGTGTGTG

ATGTGTTTGTGTGCTCCTCCTC

AACGTCGTGACGGGTGCGTGGTGTGTGTCCAA

"""

import sys

fasta = {}

seq_name = ""

sequence = ""

for line in test.split(sep="
"):

if not line.strip():

continue

if line.startswith(">"):

seq_name = line

else:

sequence = line

if seq_name not in fasta:

fasta[seq_name] = []

continue

fasta[seq_name] = sequence

結果如下:

當然原問題也有人回答了,感覺他寫的更加好看一點。

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和免費學習資料的 可以加裙 四七四五三四九五一


喜歡這篇文章嗎?立刻分享出去讓更多人知道吧!

本站內容充實豐富,博大精深,小編精選每日熱門資訊,隨時更新,點擊「搶先收到最新資訊」瀏覽吧!


請您繼續閱讀更多來自 Python 的精彩文章:

Python 如何編寫一個拼寫糾錯器?
詳解基於樸素貝葉斯的情感分析及Python實現
專為滲透測試人員設計的Python工具大合集
用 Python 進行貝葉斯模型建模(1)
為什麼Python開發越來越火?

TAG:Python |

您可能感興趣

redis-cli pipe方式導入mysql sql查詢導出redisProtocol格式數據
如何在MapReduce中使用SequenceFile數據格式?
Linux系統如何定製History輸出格式
linux使用ntfs-3g操作ntfs格式硬碟
使用 Black 自由格式化 Python
使用 pandoc 將 Markdown 轉換為格式化文檔
Canonical宣布Kotlin編程語言Snap包格式上線
Kafka-Record消息格式
企業自有數據格式雜亂,MapReduce如何搞定?
Chromium和Firefox擁抱Snap格式 可安裝在Ubuntu等發行版本
intel CPU構架bit序 Byte序 彙編指令格式
在 Linux 中使用 SoundConverter 輕鬆轉換音頻文件格式
Firefox、Edge均將支持WebP圖片格式(該格式來自Google)
蘋果將停止支持iTunes LP格式,iTunes要被放棄
蘋果HomePod支持無損格式:但iTunes卻不支持
使用 Python 處理 JSON 格式的數據
解析.DS_Store文件格式
《最終幻想8:Remastered》將只提供數字格式
Google Photos將不再為不支持的視頻格式提供免費存儲空間
蘋果將停止支持 iTunes LP 格式,iTunes 可能也會被砍