以行的形式读出一个文件最简单的方式是使用文件对象的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, typesclass CachedLineList:# Note: in Python 2.2+, it is probably worth including:# __slots__ = ('_fname')# ...and inheriting from 'object'def __init__(self, fname):self._fname = fnamedef __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 alsoreturn 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()' andsimplified 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 sysfrom os import stat, linesepfrom stat import ST_SIZEfrom random import randrangeMAX_LINE_LEN = 4096#-- Iterable classclass 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 = limitdef __iter__(self):return selfdef next(self):if self._limit <= 0:raise StopIterationself._limit -= 1pos = randrange(self._size)priorlen = min(pos, MAX_LINE_LEN)   # maybe near startself._fp.seek(pos-priorlen)# Add extra linesep at beg/end in case pos at beg/endprior = linesep + self._fp.read(priorlen)post = self._fp.read(MAX_LINE_LEN) + linesepbegln = prior.rfind(linesep) + len(linesep)endln = post.find(linesep)return prior[begln:]+post[:endln]#-- Use as command-line toolif __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文本处理之按行处理大文件相关推荐

  1. python大文本文件处理软件_Python文本处理之按行处理大文件的方法

    python 文本处理,利用python脚本处理任意文件,取希望实现功能: $logprocessor.py 其中> love,w ./readit.p被爱的人不需千军万马,毫不费力,便占据一片 ...

  2. java 按行读取大文件文件内容_Java实现按行读取大文件

    Java实现按行读取大文件 String file = "F:" + File.separator + "a.txt"; FileInputStream fis ...

  3. JAVA之NIO按行读写大文件,完美解决中文乱码问题

    JAVA之NIO按行读写大文件,完美解决中文乱码问题 参考文章: (1)JAVA之NIO按行读写大文件,完美解决中文乱码问题 (2)https://www.cnblogs.com/jpfss/p/89 ...

  4. Linux命令行下载大文件,下载Onedrive文件

    Linux命令行下载大文件,下载Onedrive文件 做深度学习实验时,经常会遇到下载数据集,下载到本地又上传到Linux服务器上,这时用rz上传会很慢,在网上找到一些方法,用curl下载One-dr ...

  5. java切割文件_Java实现按行分割大文件

    简介 工作的时候,需要将一个大的文本文件按行分割成几个小文件.本来懒得写,想网上copy一下得了,但是 gLoLdchFGpoogle 了一遍,找了几个代码写的有点乱,尝试了之后发现效率太慢了,一个 ...

  6. python读取大文件的某行_python 大文件以行为单位读取方式比对

    先前需要做一个使用python读取大文件(大于1G),并逐条存入内存进行处理的工作.做了很多的尝试,最终看到了如下的文章. 该文章实际上提供了集中读取大文件的方式,先经过测试总结如下 1. for l ...

  7. python中删除某一行_python 删除大文件中的某一行(最有效率的方法)

    用 python 处理一个文本时,想要删除其中中某一行,常规的思路是先把文件读入内存,在内存中修改后再写入源文件. 但如果要处理一个很大的文本,比如GB级别的文本时,这种方法不仅需要占用很大内存,而且 ...

  8. Java按行分割大文件

    简介 工作的时候,需要将一个大的文本文件按行分割成几个小文件.本来懒得写,想网上copy一下得了,但是 google 了一遍,找了几个代码写的有点乱,尝试了之后发现效率太慢了,一个 1000000 行 ...

  9. python局域网大文件_[源码]Python简易http服务器(内网渗透大文件传输含下载命令)...

    Python简易http服务器源码 import SimpleHTTPServer import SocketServer import sys PORT = 80 if len(sys.argv) ...

  10. python里split以制表符分隔_在python中拆分以制表符分隔的大文件

    好吧,我试着按照你的准则来做.它只在大文件中迭代一次,不必费心通过csv模块解析这些行,因为您只是在写入期间重新连接它们.在id=("a","b") start ...

最新文章

  1. Android Jetpack 组件之 Lifecycle使用
  2. window下安装Memcache
  3. python小数输出01_python:格式化输出(上)
  4. Py之Kivy:Python库之Kivy的简介、安装、使用方法之详细攻略
  5. 8.2.4临时表和正式表
  6. 离散结构和离散数学中文书_在离散数学中对场景执行的操作
  7. 在Linux上构建ASP.NET环境-asp.net关注
  8. 如何安装python3.8_python3.8下载及安装步骤详解
  9. 【第二周】结对编程(宫丽君和林莉):四则运算
  10. centos7 vsftpd 虚拟用户 pam模块认证
  11. hyperledger fabric v2.4 默认区块大小 配置文件位置
  12. C语言编程题:完美的素数
  13. GD32F103与STM32F103的区别 2021.6.2
  14. 冬奥幕后故事:从低碳火炬到AI裁判,十四年后中国科技再上场
  15. Power Switching ----- Controlling power for power shutoff
  16. matlab get(gcf,'postion ')相关解释
  17. Ogre引擎渲染系列之Normal Specular Mapping
  18. 基于OpenCV DNN模块给黑白老照片上色(附Python/C++源码)
  19. 大华摄像头视频接入(一)
  20. 利用conda安装包、卸载包、升级包、查看包信息等操作

热门文章

  1. python3数据科学入门与实战技巧_Python3数据科学入门与实战
  2. 网络原理考点之滑动窗口协议
  3. 机器视觉:线阵相机知识汇总
  4. linux u盘读取速度,linux dd命令测试U盘读写速度
  5. java解析json字符串数据
  6. Delta对冲:模拟实验
  7. Qt实战案例(18)——Qt位置相关函数汇总实例
  8. itchat 运行记录
  9. 数学建模写作指导20篇(二)-数学建模论文写作通用模板
  10. python 递归 和 动态规划 DP算法两种方法求解 最长回文子串问题