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

Python文本处理之按行处理大文件的方法,第1张

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

以行的形式读出一个文件最简单的方式是使用文件对象的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

随机行

有时候,特别是为了测试,可能需要检查某些典型的行。人们很容易就误认为一个对文本的前面几行和后面几行有效的处理就能适用任何其他地方。很不幸,很多文件的前几行和最后几行通常都是非典型的:有时候是消息头或注脚,有时候可能是开发时的日志文件的前几行等等。穷举测试整个文件并不是你想要的,通常这样也非常的耗时。

在大多数系统上,查找一个文件中的特定位置要比读出该位置前的所有内容直到到达该位置快的多。

就算使用linecache,要到达缓存行,你也需要一个字节一个字节的读取前面的内容。从一个大文件中找随机行的最快的方式是,先找到一个随机位置,然后读取该位置相对前后的少数字节。

 #-------------------- randline.py ------------------------#  #!/usr/bin/python  """Iterate over random lines in a file (req Python 2.2+)  From command-line use: % randline.py <fname> <numlines>  """  import sys  from os import stat,linesep  from stat import ST_SIZE  from random import randrange  MAX_liNE_LEN = 4096  #-- Iterable class  class randline(object):   __slots__ = ('_fp','_size','_limit')   def __init__(self,fname,limit=sys.maxint):    self._size = stat(fname)[ST_SIZE]    self._fp = open(fname,'rb')    self._limit = limit   def __iter__(self):    return self   def next(self):    if self._limit <= 0:     raise stopiteration    self._limit -= 1    pos = randrange(self._size)    priorlen = min(pos,MAX_liNE_LEN) # maybe near start    self._fp.seek(pos-priorlen)    # Add extra linesep at beg/end in case pos at beg/end    prior = linesep + self._fp.read(priorlen)    post = self._fp.read(MAX_liNE_LEN) + linesep    begln = prior.rfind(linesep) + len(linesep)    endln = post.find(linesep)    return prior[begln:]+post[:endln]  #-- Use as command-line tool  if __name__=='__main__':   fname,numlines = sys.argv[1],int(sys.argv[2])   for line in randline(fname,numlines):    print line

关于上面的实现,需要注意以下细节:

(1)在行迭代中,相同的行可能会被多次选中。当然,如果你只是从大文件中选很少行的话,这种情况通常不会出现。

(2)既然是选中包含随机位置的行,那就意味着更 有可能选择长的行(译注:这是为什么?没有明白)。

本文翻译自Text Processing in Python

中“PROBLEM: Working with lines from a large file”

以上这篇Python文本处理之按行处理大文件的方法就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持编程小技巧。

您可能感兴趣的文章:Python按行读取文件的实现方法【小文件和大文件读取】使用Python读取大文件的方法python简单读取大文件的方法python 删除大文件中的某一行(最有效率的方法)Python按行读取文件的简单实现方法Python实现模拟分割大文件及多线程处理的方法 总结

以上是内存溢出为你收集整理的Python文本处理之按行处理大文件的方法全部内容,希望文章能够帮你解决Python文本处理之按行处理大文件的方法所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/1204636.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-04
下一篇 2022-06-04

发表评论

登录后才能评论

评论列表(0条)

保存