python按指定分隔符读取文件

在处理一些结构化的文件,如fasta文件,我们往往需要读完一条记录再进行处理,如计算每条序列的长度,GC含量等等。这个时候通常的做法是按行读,先把内容存在一个临时变量,直到读到下一个区块分隔符(如fasta文件的‘>‘)的时候再处理上一条记录。如果文件不大,也可以一次读进内存,然后用split分割。前一种方法逻辑有点绕,而且容易忘记处理最后一条记录。而后一种方法对于大文件的处理就不适用了。

有没有什么方法让python以指定的分隔符读文件,而不是默认的换行符呢?我们知道perl有内建的$/变量来修改perl的默认文件分隔符,如设置$/='>'后,perl就可以每次读一条fasta记录。但是据我了解,python并没有类似的内建方法。这里提供一个十分方便的函数来按指定分隔符读文件:

1
2
3
4
5
6
7
8
9
10
11
12
def blockread(fh, sep):
buf = ""
while True:
while sep in buf:
pos = buf.index(sep)
yield buf[:pos]
buf = buf[pos + len(sep):]
chunk = fh.read(4096)
if not chunk:
yield buf
break
buf += chunk

函数第一个参数为文件句柄,第二个参数为分隔符。如果我们想遍历一个fasta文件,每次读一条fasta记录,可以使用for each in blockread(open('filename'), '>'):。该函数主要是用到yield来生成一个可迭代对象。函数的分隔符需要是字符串,经过简单修改,也可以用正则表达式作为分隔符。

如果我的博客能帮你节约时间,我会非常高兴你请我喝杯咖啡。