时间:2021-05-22
众所周知,python文件读取文件的时候所支持的newlines(即换行符),是指定的。这一点不管是从python的doucuments上还是在python的源码中(作者是参考了python的io版本,并没有阅读C版本),都可以看出来:
if newline is not None and not isinstance(newline, str): raise TypeError("illegal newline type: %r" % (type(newline),))if newline not in (None, "", "\n", "\r", "\r\n"): raise ValueError("illegal newline value: %r" % (newline,))好吧,问题来了,如果你恰好是个苦逼的生物狗,正在用python处理所谓的fastq格式的测序结果文件,每次只读一行往往不是你想要的。Ok, 我们也都知道其实这个问题在Perl里面十分好解决,无非就是重新定义下文件的分割符($/,The input record separator, newline by default. Set undef to read through the end of file.)
local $/; # enable "slurp" modelocal $_ = <FH>; # whole file now heres/\n[ \t]+/ /g;简单粗暴有效!《Programming Perl》开头的那些关于什么是happiness定义看来所言非虚,所以你只要需要将$/定义为fastq格式的分隔符就ok了。
但是,如果是Python呢?(容易钻牛角尖的孩纸,又或者是不喜欢花括号的孩子…..反正就是强行高端了)。终于要进入正题了,OK,在python中又有两种方式解决这个问题,看你个人喜好选择了(当然要是有大神知道四种、五种方法,也不妨指导一下我这个小菜鸟)。
方案一的代码:
import _pyioimport ioimport functoolsclass MyTextWrapper(_pyio.TextIOWrapper): def readrecod(self, sep): readnl, self._readnl = self._readnl, sep self._readtranslate = False self._readuniversal = False try: return self.readline() finally: self._readnl = readnl#class MyTextWrapper(_pyio.TextIOWrapper):# def __init__(self, *args, separator, **kwargs):# super().__init__(*args,**kwargs)# self._readnl = separator# self._readtranslate = False# self._readuniversal = False# print("{}:\t{}".format(self,self._readnl))f = io.open('data',mode='rt')#f = MyTextWrapper(f.detach(),separator = '>')#print(f._readnl)f = MyTextWrapper(f.detach())records=iter(functools.partial(f.readrecod, '>'), '')for r in records: print(r.strip('>')) print("###")Ok,这是Python3.x中的方法(亲测),那么在Python2.x中需要改动的地方,目测好像是(没有亲测)
super(MyTextWrapper,self).__init__(*args,**kwargs)
这个方法看上去还是比较elegant,但是efficient 吗?答案恐怕并不,毕竟放弃了C模块的速度优势,但是OOP写起来还是比较舒服的。对了值得指出的Python的I/O是一个layer一个layer的累加起来的。从这里我们就能看出来。当然里面的继承关系还是值得研究一下的,从最开始的IOBase一直到最后的TextIOWrapper,这里面的故事,还是要看一看的。
方案二的代码:
#!/usr/bin/env pythondef delimited(file, delimiter = '\n', bufsize = 4096): buf = '' while True: newbuf = file.read(bufsize) if not newbuf: yield buf return buf += newbuf lines = buf.split(delimiter) for line in lines[:-1]: yield line buf = lines[-1]with open('data', 'rt') as f: lines = delimited(f, '>', bufsize = 1) for line in lines: print line, print '######'Ok,这里用到了所谓的generator函数,优雅程度也还行,至于效率么,请自行比较和测试吧(毕竟好多生物程序猿是不关心效率的…..)。如此一来,比Perl多敲了好多代码,唉,怀念Perl的时代啊,简单粗暴有效,就是幸福的哲学么。
当然还有童鞋要问,那么能不能又elegant还efficient(我可是一个高端的生物程序猿,我要强行高端!)答案是有的,请用Cython! 问题又来了,都Cython了,为什么不直接用C呢?确实,C语言优美又混乱。
补充知识:Python.json.常见两个错误处理(Expecting , delimiter)(Invalid control character at)
ValueError: Invalid control character at: line 1 column 122(char 123)
出现错误的原因是字符串中包含了回车符(\r)或者换行符(\n)
解决方案:
转义
json_data = json_data.replace('\r', '\\r').replace('\n', '\\n')
使用关键字strict
json.loads(json_data, strict=False)
ValueError: Expecting , delimiter: line 13 column 650 (char 4186)
原因:json数据不合法,类似“group_buy_create_description_text”: “1. Select the blue “Buy” button to let other shoppers buy with you.这样的内容出现在json数据中。
解决方案:
将类似的情形通过正则筛选出来通过下面的方式处理。
正则表达式如下:
json_data = json_data.replace('""', '"########"')
js_str = '"[\s\S]+?":\s?"([\s\S]+?)"\}?\}?\]?,'
后续使用中发现无法匹配value为空的情况,故先做一下预处理
这个正则可以匹配到大部分的key,value中的value值,但是也有例外,暂时的处理方法是如果匹配结果中包含”{“, “}”, “[“, “]”这样的字符,说明是匹配失败结果,跳过处理。其他的使用下边的方法替换掉可能出问题的字符。
如果大家有更好的正则匹配方式,欢迎随时批评指正。
def htmlEscape(input) { if not input return input; input = input.replace("&", "&"); input = input.replace("<", "<"); input = input.replace(">", ">"); input = input.replace(" ", " "); input = input.replace("'", "'"); //IE暂不支持单引号的实体名称,而支持单引号的实体编号,故单引号转义成实体编号,其它字符转义成实体名称 input = input.replace("\"", """); //双引号也需要转义,所以加一个斜线对其进行转义 input = input.replace("\n", "<br/>"); //不能把\n的过滤放在前面,因为还要对<和>过滤,这样就会导致<br/>失效了 return input; }以上这篇使用Python文件读写,自定义分隔符(custom delimiter)就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持。
声明:本页内容来源网络,仅供用户参考;我单位不保证亦不表示资料全面及准确无误,也不保证亦不表示这些资料为最新信息,如因任何原因,本网内容或者用户因倚赖本网内容造成任何损失或损害,我单位将不会负任何法律责任。如涉及版权问题,请提交至online#300.cn邮箱联系删除。
作用: GROUP_CONCAT函数可以拼接某个字段值成字符串,默认的分隔符是逗号,即",", 如果需要自定义分隔符可以使用SEPARATOR 如:SEL
如下所示:data_array=np.loadtxt(filename,#文件名delimiter=',',#分隔符skiprows=1,#跳过第一行dtype
以电脑为例,文件名分隔符一般是使用圆点分隔符,但是系统文件的扩展名系统默认是从圆点分隔符开始读的,如果用多个圆点分隔符,那么系统读到第一个圆点分隔符的时候就开始
以word为例,分隔符和分页符的区别: 1、从属不同。分隔符:分隔符包括分页符、分栏符、分节符。分页符:分页符是分隔符的一种。 2、分隔不同。分隔符:分隔符
使用python实现文件导入,具体方法如下:文件样例可以自己random这里的temp1根据每一行的分隔符来读入,‘\n'表述回车temp2表示每一行内的分隔符