在处理大文件时,逐行或分块读取文件是很常见的需求。下面是几种常见的方法,用于在 Python 中分块读取文本文件:
1、问题背景
如何分块读取一个较大的文本文件,并提取出特定的信息?
- 问题描述:
f=open('blank.txt','r')
quotes=f.read()
noquotes=quotes.replace('"','')
f.close()
rf=open('blank.txt','w')
rf.write(noquotes)
rf.close()
f=open('blank.txt','r')
finished = False
postag=[]
while not finished:
line=f.readline()
words=line.split()
postag.append(words[4])
postag.append(words[6])
postag.append(words[8])
finished=True
- 使用
open()
函数打开文件,将文件内容读入变量quotes
,然后用replace()
函数去除所有双引号,再将处理后的内容写回文件。 - 再次打开文件,并使用
readline()
函数逐行读取文件内容。 - 对于每一行,将其按空格分割成一个列表
words
,并提取出列表中的第 5、7 和 9 个元素,将其添加到postag
列表中。
- 问题原因:
- 问题在于
while not finished:
循环仅迭代了文件的第一行,因此无法处理整个文件。
2、解决方案
- 使用
xml.etree.ElementTree
模块解析 XML 文件:
from xml.etree import ElementTree
line = '<word id="8" form="hibernis" lemma="hibernus1" postag="n-p---nb-" head="7" relation="ADV"/>'
element = ElementTree.fromstring(line)
form = element.attrib['form']
lemma = element.attrib['lemma']
postag = element.attrib['postag']
print(form, lemma, postag)
- 使用
ElementTree.fromstring()
方法将 XML 字符串解析成一个元素对象。 - 使用
element.attrib
获取元素的属性,并提取出form
、lemma
和postag
属性的值。 - 打印出提取出的信息。
- 使用正则表达式提取信息:
import re
data = open('x').read()
RE = re.compile('.*form="(.*)" lemma="(.*)" postag="(.*?)"', re.M)
matches = RE.findall(data)
for m in matches:
print(m)
- 使用
re.compile()
方法编译正则表达式,并将其应用到文本数据中。 - 使用
findall()
方法查找所有匹配正则表达式的子字符串,并将其存储在matches
列表中。 - 遍历
matches
列表,并打印出每个匹配子字符串。
- 使用
SAX
解析器解析 XML 文件:
import xml.sax
class Handler(xml.sax.ContentHandler):
def startElement(self, tag, attrs):
if tag == 'word':
print('form=', attrs['form'])
print('lemma=', attrs['lemma'])
print('postag=', attrs['postag'])
ch = Handler()
f = open('myfile')
xml.sax.parse(f, ch)
- 定义一个 SAX 解析器类
Handler
,并重写startElement()
方法,用于处理 XML 文件中的元素。 - 使用
xml.sax.parse()
方法解析 XML 文件,并指定解析器对象ch
。 - 每次遇到一个
word
元素,就会调用startElement()
方法,并打印出元素的form
、lemma
和postag
属性的值。
- 使用
BeautifulSoup
解析 XML 文件:
from bs4 import BeautifulSoup
soup = BeautifulSoup(open('myfile').read(), 'xml')
for word in soup.find_all('word'):
print('form=', word['form'])
print('lemma=', word['lemma'])
print('postag=', word['postag'])
- 使用
BeautifulSoup()
方法解析 XML 文件,并将其存储在soup
对象中。 - 使用
find_all()
方法查找所有word
元素,并将其存储在words
列表中。 - 遍历
words
列表,并打印出每个元素的form
、lemma
和postag
属性的值。
选择方法
- 如果需要逐行处理文件,选择方法1。
- 如果需要分块处理二进制文件或大文本文件,选择方法2。
- 如果需要按行块处理文件,选择方法3。
- 如果需要处理大规模的 CSV 文件,选择方法4。
每种方法都有其特定的应用场景,可以根据具体需求选择合适的方法。