如何使用Python计算文本文件中的总行数

27
例如,如果我的文本文件是:

For example if my text file is:


例如,如果我的文本文件如下所示:
blue
green
yellow
black

这里有四行,现在我想得到结果是四。我该怎么做?


with open('data.txt') as fp: for line in fp: if line.strip(): count += 1 - user2794146
1
是的,它可以工作,但解决方案不够Pythonic,最好使用sum() - alecxe
3
这个链接提供了如何在Python中便宜地获取行数的说明,已经足够解释了。;-) - Robert Caspary
1
可能是如何在Python中以低成本获取行数?的重复问题。 - Martin Thoma
11个回答

53
您可以使用生成器表达式与 sum() 方法一起使用:
with open('data.txt') as f:
    print sum(1 for _ in f)

请注意,您不能使用 len(f) ,因为 f 是一个迭代器。下划线 _ 是一个用于抛弃变量的特殊变量名称,请参见 Python中单个下划线“_”变量的目的是什么?
您可以使用 len(f.readlines()),但这将在内存中创建一个额外的列表,并且不会适用于不适合内存的大型文件。

2
如此Pythonic,非常Pythonic :O - SARose
如果你这样写会更快: with open('data.txt') as f: print sum([1 for _ in f]) - jimh
1
@jimh - 最好使用sum(1 for _ in f),因为它在括号内隐式地使用生成器表达式,而不创建一个1的列表。然而,你的版本sum([1 for _ in f])会在求和之前创建一个1的列表,这会不必要地分配内存。 - blokeley
@blokeley 我的问题是它是否以牺牲内存为代价更快 - jimh
@jimh 这里没有这样的权衡。生成器表达式会做更少的工作,因为它不必花时间分配内存。如果您可以重用分配的列表或字典,则推导式可以是一种优化。 - ferrix

23

这个链接 (如何在Python中快速获得行数?) 提供了许多潜在的解决方案,但它们都忽略了一种显著提高运行速度的方法,即使用未缓冲(raw)接口,使用字节数组(bytearrays)并自己进行缓冲。

使用修改后的计时工具版本,我相信下面的代码比提供的任何解决方案都更快(并且略微更符合Python语法):

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 )

这是我的时间安排:

rawpycount        0.0048  0.0046   1.00
bufcount          0.0074  0.0066   1.43
wccount             0.01    0.01   2.17
itercount          0.014   0.014   3.04
opcount            0.021    0.02   4.43
kylecount          0.023   0.021   4.58
simplecount        0.022   0.022   4.81
mapcount           0.038   0.032   6.82

我想在那里发布,但是我是Stack Exchange相对较新的用户,并没有必要的积分。

编辑:

这可以通过使用itertools中的生成器表达式完全在线完成,但它看起来很奇怪:

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 )

4
谢谢!这个itertools实现非常迅速,使我能够在读取一个非常大的文件时给出完成百分比。 - Karl Henselin
我遇到了一个错误:AttributeError: 'file' object has no attribute 'raw'。你有什么想法吗? - MD004
这里的代码是特定于Python 3的,并且原始/Unicode分割是在那里发生的。我对Python 2的记忆力现在不太好,但是如果你正在使用Python 2,我认为如果你将open()调用的模式更改为'r',并且只将"f.raw.read()"更改为"f.read()",你将在Python 2中获得相同的结果。 - Michael Bacon
将第一个示例中的返回语句更改为return sum(map(methodcaller("count", b'\n'), f_gen)),并从operator导入methodcaller,能否加快速度(如果是python2,则需要从itertools 导入'imap)?我还会将1024 * 1024`的值定义为常量,以节省一些额外的周期。同时也想看到与第二个示例的比较。 - Kumba
非常好的答案,对我很有帮助。但是我将rawbigcount中的第一行更改为with open(filename, 'rb') as f: - Sverrir Sigmundarson

8
你可以在此处使用sum()和生成器表达式。生成器表达式将是[1, 1, ...],直到文件的长度为止。然后调用sum()将它们全部加起来,得到总计数。
with open('text.txt') as myfile:
    count = sum(1 for line in myfile)

根据你尝试过的情况来看,似乎你不想包含空行。那么你可以这样做:

with open('text.txt') as myfile:
    count = sum(1 for line in myfile if line.rstrip('\n'))

5
count=0
with open ('filename.txt','rb') as f:
    for line in f:
        count+=1

print count

2

一句话描述:

total_line_count = sum(1 for line in open("filename.txt"))

print(total_line_count)

0

以下是使用列表推导式的方法,但这会浪费一点计算机内存,因为 line.strip() 被调用了两次。

     with open('textfile.txt') as file:
lines =[
            line.strip()
            for line in file
             if line.strip() != '']
print("number of lines =  {}".format(len(lines)))

0

这个功能还可以返回文件中的行数。

a=open('filename.txt','r')
l=a.read()
count=l.splitlines()
print(len(count))

0
如果你导入了pandas,那么你可以使用shape函数来确定它。不确定它的性能如何。代码如下:
import pandas as pd
data=pd.read_csv("yourfile") #reads in your file
num_records=[]               #creates an array 
num_records=data.shape       #assigns the 2 item result from shape to the array
n_records=num_records[0]     #assigns number of lines to n_records

0

我不是第一次来Stack Overflow,只是以前没有账号,通常都是在这里找答案。我还不能评论或投票支持答案。但是我想说,Michael Bacon上面的代码非常好用。虽然我是Python新手,但我对编程并不陌生。我一直在阅读《Python Crash Course》,但我想打破一下从头到尾阅读的方式,做一些其他的事情。其中一个实用工具是从ETL或数据质量的角度捕获文件的行数,而不受任何ETL的影响。文件有X行,你将其导入SQL或Hadoop,最终得到的也是X行。你可以在最低层次上验证原始数据文件的行数。

我一直在测试他的代码,这个代码非常高效。我创建了几个不同大小和行数的CSV文件,你可以看到我的代码和注释提供的时间和细节。Michael Bacon提供的代码比普通的Python方法(只是循环行)运行速度快6倍左右。

希望这能帮助到某些人。


 import time
from itertools import (takewhile,repeat)

def readfilesimple(myfile):

    # watch me whip
    linecounter = 0
    with open(myfile,'r') as file_object:
        # watch me nae nae
         for lines in file_object:
            linecounter += 1

    return linecounter

def readfileadvanced(myfile):

    # watch me whip
    f = open(myfile, 'rb')
    # watch me nae nae
    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)
    #return linecounter


# ************************************
# Main
# ************************************

#start the clock

start_time = time.time()

# 6.7 seconds to read a 475MB file that has 24 million rows and 3 columns
#mycount = readfilesimple("c:/junk/book1.csv")

# 0.67 seconds to read a 475MB file that has 24 million rows and 3 columns
#mycount = readfileadvanced("c:/junk/book1.csv")

# 25.9 seconds to read a 3.9Gb file that has 3.25 million rows and 104 columns
#mycount = readfilesimple("c:/junk/WideCsvExample/ReallyWideReallyBig1.csv")

# 5.7 seconds to read a 3.9Gb file that has 3.25 million rows and 104 columns
#mycount = readfileadvanced("c:/junk/WideCsvExample/ReallyWideReallyBig1.csv")


# 292.92 seconds to read a 43Gb file that has 35.7 million rows and 104 columns
mycount = readfilesimple("c:/junk/WideCsvExample/ReallyWideReallyBig.csv")

# 57 seconds to read a 43Gb file that has 35.7 million rows and 104 columns
#mycount = readfileadvanced("c:/junk/WideCsvExample/ReallyWideReallyBig.csv")


#stop the clock
elapsed_time = time.time() - start_time


print("\nCode Execution: " + str(elapsed_time) + " seconds\n")
print("File contains: " + str(mycount) + " lines of text.")

0

对于建议使用 with open("filename.txt", "r") as f 的人,你可以使用 anyname = open("filename.txt", "r")

def main():

    file = open("infile.txt",'r')
    count = 0
    for line in file:
            count+=1

    print (count)

main ()

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