def _make_gen(reader):
b = reader(1024 * 1024)
while b:
yield b
b = reader(1024*1024)
def rawpycount(filename):
f = open(filename, 'rb')
f_gen = _make_gen(f.raw.read)
return sum( buf.count(b'\n') for buf in f_gen )
from itertools import (takewhile,repeat)
def rawbigcount(filename):
f = open(filename, 'rb')
bufgen = takewhile(lambda x: x, (f.raw.read(1024*1024) for _ in repeat(None)))
return sum( buf.count(b'\n') for buf in bufgen if buf )
可以对生成器表达式使用^{} :
注意,不能使用
len(f)
,因为f
是iterator。_
是一次性变量的特殊变量名,请参见What is the purpose of the single underscore "_" variable in Python?。您可以使用
len(f.readlines())
,但这将在内存中创建一个额外的列表,这甚至无法处理不适合内存的大型文件。这个链接(How to get line count cheaply in Python?)有很多潜在的解决方案,但它们都忽略了一种使运行速度大大加快的方法,即使用无缓冲(raw)接口、使用bytearray和执行自己的缓冲。
使用一个经过修改的计时工具,我相信下面的代码比提供的任何解决方案都要快(稍微更像是pythonic):
以下是我的时间安排:
我会贴在那里,但我是一个相对新的用户堆栈交换,没有必要的甘露。
编辑:
这完全可以使用itertools的生成器表达式来完成,但是看起来很奇怪:
您可以在这里将
sum()
与生成器表达式一起使用。生成器表达式将是[1, 1, ...]
,长度不超过文件的长度。然后我们调用sum()
将它们全部相加,得到总数。从你的尝试来看,你似乎不想包含空行。然后您可以:
相关问题 更多 >
编程相关推荐