溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

使用Python文件讀寫,自定義分隔符的方法

發(fā)布時間:2020-07-06 11:07:56 來源:億速云 閱讀:486 作者:清晨 欄目:開發(fā)技術

小編給大家分享一下使用Python文件讀寫,自定義分隔符的方法,希望大家閱讀完這篇文章后大所收獲,下面讓我們一起去探討吧!

眾所周知,python文件讀取文件的時候所支持的newlines(即換行符),是指定的。這一點不管是從python的doucuments上還是在python的源碼中,都可以看出來:

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" mode
local $_ = <FH>; # whole file now here
s/\n[ \t]+/ /g;

簡單粗暴有效!《Programming Perl》開頭的那些關于什么是happiness定義看來所言非虛,所以你只要需要將$/定義為fastq格式的分隔符就ok了。

但是,如果是Python呢?。終于要進入正題了,OK,在python中又有兩種方式解決這個問題,看你個人喜好選擇了。

方案一的代碼:

import _pyio
import io
import functools
class 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模塊的速度優(yōu)勢,但是OOP寫起來還是比較舒服的。對了值得指出的Python的I/O是一個layer一個layer的累加起來的。從這里我們就能看出來。當然里面的繼承關系還是值得研究一下的,從最開始的IOBase一直到最后的TextIOWrapper,這里面的故事,還是要看一看的。

方案二的代碼:

#!/usr/bin/env python

def 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函數(shù),優(yōu)雅程度也還行,至于效率么,請自行比較和測試吧(畢竟好多生物程序猿是不關心效率的…..)。如此一來,比Perl多敲了好多代碼,唉,懷念Perl的時代啊,簡單粗暴有效,就是幸福的哲學么。

當然還有童鞋要問,那么能不能又elegant還efficient(我可是一個高端的生物程序猿,我要強行高端!)答案是有的,請用Cython! 問題又來了,都Cython了,為什么不直接用C呢?確實,C語言優(yōu)美又混亂。

補充知識:Python.json.常見兩個錯誤處理(Expecting , delimiter)(Invalid control character at)

ValueError: Invalid control character at: line 1 column 122(char 123)

出現(xiàn)錯誤的原因是字符串中包含了回車符(\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數(shù)據(jù)不合法,類似“group_buy_create_description_text”: “1. Select the blue “Buy” button to let other shoppers buy with you.這樣的內容出現(xiàn)在json數(shù)據(jù)中。

解決方案:

將類似的情形通過正則篩選出來通過下面的方式處理。

正則表達式如下:

json_data = json_data.replace('""', '"########"')

js_str = '"[\s\S]+&#63;":\s&#63;"([\s\S]+&#63;)"\}&#63;\}&#63;\]&#63;,'

后續(xù)使用中發(fā)現(xiàn)無法匹配value為空的情況,故先做一下預處理

這個正則可以匹配到大部分的key,value中的value值,但是也有例外,暫時的處理方法是如果匹配結果中包含”{“, “}”, “[“, “]”這樣的字符,說明是匹配失敗結果,跳過處理。其他的使用下邊的方法替換掉可能出問題的字符。

如果大家有更好的正則匹配方式,歡迎隨時批評指正。

def htmlEscape(input) {
    if not input
      return input;
    input = input.replace("&", "&amp;");
    input = input.replace("<", "&lt;");
    input = input.replace(">", "&gt;");
    input = input.replace(" ", "&nbsp;");
    input = input.replace("'", "&#39;");  //IE暫不支持單引號的實體名稱,而支持單引號的實體編號,故單引號轉義成實體編號,其它字符轉義成實體名稱
    input = input.replace("\"", "&quot;"); //雙引號也需要轉義,所以加一個斜線對其進行轉義
    input = input.replace("\n", "<br/>"); //不能把\n的過濾放在前面,因為還要對<和>過濾,這樣就會導致<br/>失效了
    return input;
  }

看完了這篇文章,相信你對使用Python文件讀寫,自定義分隔符的方法有了一定的了解,想了解更多相關知識,歡迎關注億速云行業(yè)資訊頻道,感謝各位的閱讀!

向AI問一下細節(jié)

免責聲明:本站發(fā)布的內容(圖片、視頻和文字)以原創(chuàng)、轉載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權內容。

AI