【ROSALIND】【練Python,學(xué)生信】65 從基因序列構(gòu)建字符表

如果第一次閱讀本系列文檔請(qǐng)先移步閱讀【ROSALIND】【練Python,學(xué)生信】00 寫(xiě)在前面 ?謝謝配合~

題目:
從基因序列構(gòu)建字符表(Creating a Character Table from Genetic Strings)
?
Given: A collection of at most 100 characterizable DNA strings, each of length at most 300 bp.
所給:不超過(guò)100條可表征的DNA序列,每條序列不超過(guò)300bp。
Return: A character table for which each nontrivial character encodes the symbol choice at a single position of the strings. (Note: the choice of assigning '1' and '0' to the two states of each SNP in the strings is arbitrary.).
需得:一個(gè)字符表,其中每個(gè)字符在各條序列此位置的情況進(jìn)行編碼。(提醒:各位置賦值“1”或“0”是任意的。)
?
測(cè)試數(shù)據(jù)
ATGCTACC
CGTTTACC
ATTCGACC
AGTCTCCC
CGTCTATC
測(cè)試輸出
10110
10100
?
生物學(xué)背景
? ? ? ? 在55 創(chuàng)建字符表中,我們從進(jìn)化樹(shù)推出了字符表。但在實(shí)際操作中情況是相反的,我們需要先生成字符表,再在這個(gè)基礎(chǔ)上構(gòu)建系統(tǒng)發(fā)育模型?,F(xiàn)代遺傳學(xué)中,我們常通過(guò)對(duì)SNP的分析實(shí)現(xiàn)這一過(guò)程,對(duì)于給定的一組序列,我們可以用某個(gè)核苷酸位點(diǎn)上的不同來(lái)將這組序列分成兩組。
?
思路
? ? ? ??對(duì)于我來(lái)說(shuō),這道題的題面非?;逎y懂,我在看了所給示例和其他人的解答代碼后才大概理解了要做什么,我們先來(lái)看一下測(cè)試數(shù)據(jù),一共有5條序列:
ATGCTACC
CGTTTACC
ATTCGACC
AGTCTCCC
CGTCTATC
? ? ? ??我們根據(jù)序列可以畫(huà)出下面這幅圖:

? ? ? ??也就是說(shuō),所給的序列是“可表征的(characterizable)”,即在每一個(gè)位點(diǎn)(列)上,最多只存在兩種可能,根據(jù)每個(gè)位點(diǎn)的情況都可以把這些序列分成兩類(lèi)。但一個(gè)類(lèi)里只有超過(guò)一個(gè)元素才有意義,所以輸出結(jié)果時(shí)把只有一個(gè)或沒(méi)有不一樣值的列給刪掉了。在本例中,只有前兩列有超過(guò)一個(gè)不一樣值,因此結(jié)果為:
10110
10100
? ? ? ??接下來(lái)就是如何用python實(shí)現(xiàn),我再次抄了別人的解答代碼(原地址:https://github.com/fedeoliv/Rosalind-Problems/blob/master/cstr.py)。可以看到,這個(gè)代碼非常簡(jiǎn)潔緊湊,閱讀難度也較大,我這里幫大家梳理一下過(guò)程。
? ? ? ??首先,讀入數(shù)據(jù)文件,將序列傳入到get_character_table()函數(shù)中。
? ? ? ??進(jìn)入get_character_table()后,首先要把序列從橫著的一行一行存儲(chǔ),變成豎著的一列一列存儲(chǔ)。這里用的語(yǔ)句是''.join, zip(*dna_strings)。其中,zip(*)函數(shù)首先用星號(hào)(*)操作符解包,把之前完整的一個(gè)一個(gè)序列變成單個(gè)字符,然后zip再把每一條序列某一位上的元素挨個(gè)取出來(lái),拼成一個(gè)新的字符串。
? ? ? ??把新字符串拼好后,用map(s[0].__eq__, s)將每一個(gè)列所有字符都與第一個(gè)字符比較,如果一致會(huì)返回1,反之返回0,把這些結(jié)果拼起來(lái)。
? ? ? ??最后,用sum(map(int, k))去判斷每列有幾個(gè)不一樣的值,顯然,如果整列都一樣,sum的結(jié)果將會(huì)是0或len(k),如果只有一個(gè)不一樣的值,結(jié)果會(huì)是1或len(k) - 1,排除掉這兩個(gè)情況,剩下的就是最終要得到的結(jié)果了。
?
?代碼