2017-08-12 168 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

在这种情况下,“消费”仅仅意味着“从文件中逐行读取行,直到整个文件被读取”。 –