有没有办法在不逐行迭代的情况下确定文件中有多少行?

4

可能是重复问题:
如何在Python中以低成本获得行数?

你好。下面是一些代码,实现了逐行读取文件和计数器迭代。

def __set_quantity_filled_lines_in_file(self):
    count = 0
    with open(self.filename, 'r') as f:
        for line in f:
             count += 1
    return count

我的问题是,有没有方法可以确定当前文件中有多少行文本数据而不需要逐行迭代?谢谢!

谢谢你,Paolo。这是相同的问题。 - Dmitry Zagorulkin
更好的使用缓冲区读取行的方法。 - Dmitry Zagorulkin
这个问题也与编程有关。 - Lev Levitsky
“重复”评论获得了4个赞,但只有3个关闭投票? - glglgl
2
@glglgl:我不知道这是否是原因,但新用户在获得关闭投票权限之前可以对评论进行投票。 - Steve Jessop
@SteveJessop 哦,好的,我没想到那个。 (不过无所谓,只是好奇而已。) - glglgl
5个回答

5

通常情况下,最好的方法是读取文件中的每个字符并计算换行符。

如果您了解文件的内部结构,则可能可以实现更好的效果。例如,如果文件长度为1024kB,每行长度为1kB,则可以推断文件中有1024行。


每行字符数量不同,但感谢您的提问! - Dmitry Zagorulkin

3

我不确定Python是否有这个功能,但我非常怀疑。如果有的话,它基本上需要读取整个文件。换行符由\n字符(实际上是系统相关的)表示,因此没有办法在不读取整个文件的情况下知道文件中有多少个换行符。


1

不,这样的信息只能通过迭代整个文件内容(或将整个文件读入内存)来检索。但是,除非您确定文件始终很小,否则最好不要考虑这样做。

即使您不循环遍历文件内容,您调用的函数也会这样做。例如,len(f.readlines())将读取整个文件到一个列表中,仅仅为了计算元素的数量。这是极其低效的,因为您根本不需要存储文件内容。


我认为这里的其他帖子已经证明了这个说法是不正确的。迭代并不是唯一的方法。 - Jay M
2
@JasonMorgan - 你是在说你知道如何在小于O(n)的时间内计算文件中\r\n出现的次数吗?如果是,请提供详细信息。 - Li-aung Yip
1
@JasonMorgan 除了迭代文件内容之外,您的Counter()还有什么其他功能?而您的f.read()除了读取整个文件内容之外,还需要不必要的大量内存吗? - glglgl
2
@JasonMorgan:我说的不是代码,而是实际发生的事情。len(r.readlines()) 可以自动完成迭代,但整个文件会被读入列表中,然后在确定长度后被丢弃。因此这是一种浪费内存的做法(尽管时间很短)。 - ThiefMaster
谢谢Jason。我想我会在另一个进程中将信息写入文件的几个字节中。当需要了解文件中有多少行文本时,我将读取这些字节。 - Dmitry Zagorulkin
抱歉,也许我表达不够清楚。我的意思是,在Python中迭代并不是唯一的方法。低级语言在查找内存中的模式时要快得多。例如,在我的答案中使用了collections模块,这是编译代码,而不是Python代码。正如其他人所说,您可以编写自己优化的模块并进行封装。 - Jay M

1
你可以使用`readlines()`文件方法,这可能是最简单的方法。
如果你想不同,你可以使用`read()`成员函数获取整个文件,并使用`collections.Counter`类计数CR、LF、CRLR和LFCR字符组合。但是,你将需要处理各种终止行的方式。
类似以下内容:
import collections
f=open("myfile","rb")
d=f.read()
f.close()
c=collections.Counter(d)
lines1=c['\r\n']
lines2=c['\n\r']
lines3=c['\r']-lines1-lines2
lines4=c['\n']-lines1-lines2
nlines=lines3+lines4

我不关心最简单的方法,我正在寻找一种可扩展的、执行此操作最快的方式。 - Dmitry Zagorulkin
假设您的文件始终小于2G,最快且最可扩展的方法是使用C语言完成。在C语言中创建一个Python扩展程序,仅从内存缓冲区计算行数。 - Jay M
“\n\r”在大多数平台上会被视为两行,对吗? - anatoly techtonik
@JasonMorgan,不行-这种方法行不通-https://dev59.com/3onda4cB1Zd3GeqPEMwb - anatoly techtonik
@techtonik 我已经在我的回答中说明了,如果需要,您将不得不处理多个平台。感谢您提供与此相关的其他问题的链接。 - Jay M

0
这会给出答案,但是会读取整个文件并将每一行存储在一个列表中。
    len(f.readlines())

1
因此需要不必要的大量内存。 - glglgl

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接