首页 > 编程 > Python > 正文

Python文本处理之按行处理大文件的方法

2020-02-22 23:39:21
字体:
来源:转载
供稿:网友

以行的形式读出一个文件最简单的方式是使用文件对象的readline()、readlines()和xreadlines()方法。

Python2.2+为这种频繁的操作提供了一个简化的语法——让文件对象自身在行上高效迭代(这种迭代是严格的向前的)。

为了读取整个文件,可能要使用read()方法,且使用字符串的split()来将它拆分WEIGHT行或其他块。

下面是一些例子:

  >>> for line in open('chap1.txt'): # Python 2.2+  ...  # process each line in some manner  ...  pass  ...  >>> linelist = open('chap1.txt').readlines()  >>> print linelist[1849],  EXERCISE: Working with lines from a large file  >>> txt = open('chap1.txt').read()  >>> from os import linesep  >>> linelist2 = txt.split(linesep)

如果文件不大,读取整个文件内容也没有关系。但如果是大文件,时间和内存就是要重点关注的了。比如,复杂文档或者活动日志文件,通常有上M,甚至很多G的大小。就算这些文件的内容没有超出可用内存的尺寸,读取他们仍然是相当耗时的。

很明显,如果你需要处理文件的每一行,那就必须读取整个文件;如果可以按序列处理,xreadlines方法是一种更节约内存的方法。但是对于那些仅仅需要一个大文件的一部分行的应用,要获得提高其实并不难。对于这一点,模块“linecache”非常合适。

具有缓存功能的行列表

使用linecache可以直接从一个文件中读取指定行:

  >>> import linecache  >>> print linecache.getline('chap1.txt',1850),  PROBLEM: Working with lines from a large file

记住,linecache.getline()的计数是从1开始的。

如果有一个即具有“linecache”的效率,又有列表的一些功能的对象就好了。这个对象不仅可以枚举和索引,同时还支持切片。

#------------------ cachedlinelist.py --------------------#  import linecache, types  class CachedLineList:   # Note: in Python 2.2+, it is probably worth including:   # __slots__ = ('_fname')   # ...and inheriting from 'object'   def __init__(self, fname):    self._fname = fname   def __getitem__(self, x):    if type(x) is types.SliceType:     return [linecache.getline(self._fname, n+1)       for n in range(x.start, x.stop, x.step)]    else:     return linecache.getline(self._fname, x+1)   def __getslice__(self, beg, end):    # pass to __getitem__ which does extended slices also    return self[beg:end:1]

使用这个新对象几乎和使用一个由“open(fname).readlines()”创建的列表一样。除了它的效率要更高之外(特别是在内存使用方面):

  >>> from cachedlinelist import CachedLineList  >>> cll = CachedLineList('../chap1.txt')  >>> cll[1849]  ' PROBLEM: Working with lines from a large file/r/n'  >>> for line in cll[1849:1851]: print line,  ...  PROBLEM: Working with lines from a large file  ----------------------------------------------------------  >>> for line in cll[1853:1857:2]: print line,  ...  a matter of using the '.readline()', '.readlines()' and  simplified syntax for this frequent operation by letting the            
发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表