2017-08-12 64 views
3

我正在編寫一個應該返回最小序列比對分數(較小=較好)的程序,它與Coursera樣本輸入一起工作,但對於我們給出的數據集,我不能手動輸入序列,所以我不得不求助於使用文本文件。有幾件事我覺得很奇怪。第一 第一件事,奇怪的值更改而不更改文本文件Python

pattern = 'AAA' 
DNA = open('practice_data.txt') 
empty = [] 
for lines in DNA: 
     line=lines.strip().strip('\n') 
     empty.append(line) 
print(empty) 
print(smallest_distance(pattern, DNA))  

如果我運行它,我的程序輸出0。如果我註釋掉的for循環,我的計劃產出2.我沒有改變DNA,所以爲什麼要我的程序不同的表現?此外,我的帶子('\ n')正在工作(出於某種原因,帶子('n')也可以工作),但是我的帶子()不工作。一旦我明白了這一點,我可以在我的smallest_distance函數中測試空。

這裏是我的數據是這樣的:

ACTAG 
CTTAGTATCACTCTGAAAAGAGATTCCGTATCGATGACCGCCAGTTAATACGTGCGAGAAGTGGACACGGCCGCCGACGGCTTCTACACGCTATTACGATG AACCAACAATTGCTCGAATCCTTCCTCAAAATCGCACACGTCTCTCTGGTCGTAGCACGGATCGGCGACCCACGCGTGACAGCCATCACCTATGATTGCCG 
TTAAGGTACTGCTTCATTGATCAACACCCCTCAGCCGGCAATCACTCTGGGTGCGGGCTGGGTTTACAGGGGTATACGGAAACCGCTGCTTGCCCAATAAT 

etc... 
+0

請給practice_data.txt重構了一下。您可以在gist.github.com上發帖,並將鏈接提供給我們。 –

+1

'for'循環消耗'DNA'。如果你評論它,它不會。這可能會影響'smallest_distance(pattern,DNA)'調用。 – janos

+1

[你可能對這個CodeReview問題感興趣](https://codereview.stackexchange.com/questions/135217/matlab-implementation-of-needleman-wunsch-algorithm) –

回答

1

解決方案:

pattern = 'AAA' 
with open('practice_data.txt') as f_dna: 
    dna_list = [sequence for line in f_dna for sequence in line.split()] 
print(smallest_distance(pattern, dna_list)) 

說明:

你是接近的解決方案,但你需要通過split()

到remplace strip() - >strip()刪除多餘的字符,所以你strip('\n')是一個很好的猜測。 但由於\n是在該行的結束,因爲這是算作一個delimitor拆分將自動擺脫它

>>> 'test\ntest'.split() 
>>> ['test', 'test'] 

>>> 'test\n'.split() 
>>> ['test'] 

現在,你必須通過列表之間的簡單相加remplace .append()自分割以來的操作返回list

DNA = open('practice_data.txt') 
empty = [] 
for lines in DNA: 
    line = lines.split() 
    empty += line 

,還有在你的代碼中的一些問題:

這是更好地使用with聲明在打開一個文件,因爲它會自動處理異常,並在年底關閉文件描述符:

empty = [] 
with open('practice_data.txt') as DNA: 
    for lines in DNA: 
     line = lines.split() 
     empty += line 

你的代碼現在很好,你仍然可以使用重構列表理解(Python中很常見)

with open('practice_data.txt') as DNA: 
    empty = [sequence for line in DNA for sequence in line.split()] 

如果您對此有所瞭解,嘗試以重新組織它循環

empty = [] 
with open('practice_data.txt') as DNA: 
    for line in DNA: 
     for sequence in line.split(): 
      empty.append(sequence) 

注意:@MrGeek解決方案工作,但作爲兩個主要的默認設置:

  • ,因爲它沒有使用with聲明,該文件是永遠不會關閉,導致內存問題,
  • 使用.read().splitlines()將加載內存中的文件的所有內容,這可能導致MemoryError例外,如果該文件太大。

走得更遠,處理大文件:

,你必須充滿DNA序列的1GO文件,即使你不加載在內存中的所有文件

現在成像,你仍然有巨大的dict,更好的初步實踐將創造結果的另一個文件,並處理對飛你的DNA:

pattern = 'AAA' 
with open('practice_data.txt') as f_dna, open('result.txt', 'w') as f_result: 
    for line in DNA: 
     for sequence in line.split(): 
      result = smallest_distance(pattern, sequence) 
      f_result.write(result) 

警告:您將不得不確保您的功能smallest_distance接受string而不是list

如果不可能,您可能需要處理批處理,但由於它有點複雜,所以我不會在此討論這個問題。現在

可以使用例如genetor功能,提高可讀性

def extract_sequence(file, pattern): 
    for line in file: 
     for sequence in line.split(): 
      yield smallest_distance(pattern, sequence) 

pattern = 'AAA' 
with open('practice_data.txt') as f_dna, open('result.txt', 'w') as f_result: 
    for result in extract_sequence(f_dna, pattern): 
     f_result.write(result) 
+1

真棒解釋!感謝您抽出時間解釋爲什麼即使某些方法能夠得到答案,也不應該因爲其他原因而使用它們。是的,我確實理解列表理解,但無論如何感謝徹底! – DrJessop

+0

@DrJessop,在編寫嵌套列表理解之前,也是爲了我,我總是先做'for循環',然後再重構^^'無論如何,我很高興你喜歡這個解釋! –

0

寫:

pattern = 'AAA' 
DNA = open('practice_data.txt').read().splitlines() 
newDNA = [] 
for line in DNA: 
    newDNA += line.split() # create an array with strings then concatenate it with the newDNA array 
print(smallest_distance(pattern, newDNA)) 
+0

我試過這個,出於某種原因,我只是在我的列表中獲取兩個字符串。第一行一個,其餘一個 – DrJessop

+0

在這裏空空蕩蕩的角色扮演什麼角色? –

+0

我想創建一個文本文件中所有字符串的列表,而不必手動輸入它們。 – DrJessop

1

潛在錯誤:

print(smallest_distance(pattern, DNA)) 

DNA是文件描述符,而不是一個字符串數組。因爲DNA = open('practice_data.txt')

For循環消耗DNA。因此,如果您正在以smallest_distance再次使用循環for lines in DNA:,則不起作用。

更新: 在這種情況下,for循環從文件開始到結束。它不會像列表一樣再次返回。除非你打電話DNS.close()並重新初始化再次DNA = open('practice_data.txt')

一個簡單的例子文件描述符,你可以嘗試

DNA = open('text.txt') 
for lines in DNA: 
     line=lines.strip().strip('\n') 
     print (line) # print everything in the file here 

print ('try again') 
for lines in DNA: 
     line=lines.strip().strip('\n') 
     print (line) # will not print anything at all 

print ('done') 

閱讀For loop not working twice on the same file descriptor更多細節

+0

我一直聽到這個詞「消費」。你是什​​麼意思?消耗系統內存? – DrJessop

+0

感謝您的資源 – DrJessop

+0

在這種情況下,「消費」僅僅意味着「從文件中逐行讀取行,直到整個文件被讀取」。 –