Pythonで安価に大きなファイルの行数を取得する方法は?


1012

Pythonで大きなファイル(数十万行)の行数を取得する必要があります。メモリと時間の両方で最も効率的な方法は何ですか?

現時点で私は:

def file_len(fname):
    with open(fname) as f:
        for i, l in enumerate(f):
            pass
    return i + 1

より良いことはできますか?


7
正確な行数が必要ですか、それとも近似で十分ですか?
ピコ

43
このコードは空のファイルでは機能しないため、forループの前にi = -1を追加します。
Maciek Sawicki

12
@凡例:picoが考えているに違いない、ファイルサイズを取得(seek(0,2)またはequivを使用)、おおよその行の長さで除算。最初に数行を読んで、平均行長を推測できます。
アン

32
enumerate(f, 1)そして、捨てi + 1ますか?
Ian Mackinnon 2013

4
@IanMackinnon空のファイルで機能しますが、forループの前にi0に初期化する必要があります。
scai 2013

回答:


357

それ以上のものはありません。

結局のところ、どのようなソリューションでも、ファイル全体を読み取って、その数\nを調べ、その結果を返す必要があります。

ファイル全体を読み取らずにそれを行うより良い方法はありますか?わからない...最善の解決策は常にI / Oバウンドです。最善の解決策は、不要なメモリを使用しないことですが、それをカバーしているように見えます。


7
WCでもファイルを読み取っていますが、Cではかなり最適化されています。
オラフルWaage

6
私が理解している限り、PythonファイルのIOもCを介して行われます。docs.python.org/library/stdtypes.html#file-objects
2009年

9
@トマラックそれは赤いニシンです。pythonとwcは同じsyscallsを発行している可能性がありますが、pythonにはwcにはないopcodeディスパッチのオーバーヘッドがあります。
bobpoekert 2013年

4
サンプリングによって行数を概算できます。何千倍も速くなる可能性があります。参照:documentroot.com/2011/02/...
エリックAronesty

4
他の回答は、このカテゴリー別の回答が間違っていることを示しているようです。そのため、承認されたままにするのではなく、削除する必要があります。
Skippy le Grand Gourou 2017年

625

1行、おそらくかなり高速:

num_lines = sum(1 for line in open('myfile.txt'))

8
sum(sequence of 1)と同様に、すべての行が1としてカウントされます。>>> [range(10)の行に対して1] [1、1、1、1、1、1、1、1、1、1] >>> sum(1 for range(10))10 >>>
James Sapam

4
num_lines = sum(1(open( 'myfile.txt')の行の場合は、line.rstrip()の場合)、空の行をフィルターします
Honghe.Wu

61
ファイルを開くときに、すべての要素を反復処理すると、ファイルは自動的に閉じられますか?「close()」が必要ですか?この短いステートメントで「with open()」を使用することはできないと思いますよね?
Mannaggia 14年

16
@Mannaggia正解です。「with open(filename)」を使用してファイルが閉じられたことを確認することをお勧めします。さらに、try-exceptブロック内でこれを行うと、IOError例外がスローされます。ファイルを開くことができません。
BoltzmannBrain、

17
もう1つの注意点:これは、元の問題が30万行のテキストファイルに与えたものよりも0.04〜0.05秒遅い
andrew

202

メモリマップファイルが最速のソリューションになると思います。私は4つの関数を試しましたopcount。ファイル内の行を単純に繰り返します(simplecount); メモリマップファイル(mmap)(mapcount);を使用したreadline Mykola Kharechkoが提供するバッファ読み取りソリューション(bufcount)。

各関数を5回実行し、120万行のテキストファイルの平均実行時間を計算しました。

Windows XP、Python 2.5、2 GB RAM、2 GHz AMDプロセッサ

これが私の結果です:

mapcount : 0.465599966049
simplecount : 0.756399965286
bufcount : 0.546800041199
opcount : 0.718600034714

編集:Python 2.6の数値:

mapcount : 0.471799945831
simplecount : 0.634400033951
bufcount : 0.468800067902
opcount : 0.602999973297

したがって、バッファの読み取り戦略は、Windows / Python 2.6の場合は最速のようです

これがコードです:

from __future__ import with_statement
import time
import mmap
import random
from collections import defaultdict

def mapcount(filename):
    f = open(filename, "r+")
    buf = mmap.mmap(f.fileno(), 0)
    lines = 0
    readline = buf.readline
    while readline():
        lines += 1
    return lines

def simplecount(filename):
    lines = 0
    for line in open(filename):
        lines += 1
    return lines

def bufcount(filename):
    f = open(filename)                  
    lines = 0
    buf_size = 1024 * 1024
    read_f = f.read # loop optimization

    buf = read_f(buf_size)
    while buf:
        lines += buf.count('\n')
        buf = read_f(buf_size)

    return lines

def opcount(fname):
    with open(fname) as f:
        for i, l in enumerate(f):
            pass
    return i + 1


counts = defaultdict(list)

for i in range(5):
    for func in [mapcount, simplecount, bufcount, opcount]:
        start_time = time.time()
        assert func("big_file.txt") == 1209138
        counts[func].append(time.time() - start_time)

for key, vals in counts.items():
    print key.__name__, ":", sum(vals) / float(len(vals))

1
メモリマップファイル全体がメモリに読み込まれていません。OSが必要に応じてRAMにスワップしたり、RAMからスワップアウトしたりする仮想メモリ空​​間を取得します。ここでは、Windows上で処理している方法は次のとおりです。msdn.microsoft.com/en-us/library/ms810613.aspx
ライアンGinstrom

1
申し訳ありませんが、ここにメモリマップファイルに関するより一般的なリファレンスがあります:en.wikipedia.org/wiki/Memory-mapped_fileそして、投票に感謝します。:)
ライアンギストロム2009年

1
これは単なる仮想メモリですが、まさにこのアプローチを制限するものであるため、巨大なファイルに対しては機能しません。私はそれを10ミリ以上の1.2Gbファイルで試しました。行(wc -lで取得)とWindowsErrorを取得:[エラー8]このコマンドを処理するのに十分なストレージがありません。もちろん、これはエッジケースです。
SilentGhost 2009年

6
+1は実際のタイミングデータです。1024 * 1024のバッファサイズが最適であるかどうか、またはより良いものがあるかどうかを知っていますか?
Kiv

28
それwccount()は最速のgist.github.com/0ac760859e614cd03652
jfs

133

私の評判スコアが少し上がるまで、同様の質問にこれを投稿しなければなりませんでした(私をぶつけた人に感謝します!)。

これらのソリューションはすべて、これを大幅に高速化する1つの方法を無視します。つまり、バッファリングされていない(raw)インターフェイスを使用し、バイト配列を使用し、独自のバッファリングを実行します。(これはPython 3にのみ適用されます。Python2では、rawインターフェースはデフォルトで使用される場合と使用されない場合がありますが、Python 3ではデフォルトでUnicodeになります。)

タイミングツールの変更されたバージョンを使用すると、次のコードは、提供されているどのソリューションよりも高速(そしてわずかにPythonic)だと思います。

def rawcount(filename):
    f = open(filename, 'rb')
    lines = 0
    buf_size = 1024 * 1024
    read_f = f.raw.read

    buf = read_f(buf_size)
    while buf:
        lines += buf.count(b'\n')
        buf = read_f(buf_size)

    return lines

別のジェネレーター関数を使用すると、smidgeがより速く実行されます。

def _make_gen(reader):
    b = reader(1024 * 1024)
    while b:
        yield b
        b = reader(1024*1024)

def rawgencount(filename):
    f = open(filename, 'rb')
    f_gen = _make_gen(f.raw.read)
    return sum( buf.count(b'\n') for buf in f_gen )

これはitertoolsを使用してインラインでジェネレーター式で完全に実行できますが、見た目がかなり奇妙になります。

from itertools import (takewhile,repeat)

def rawincount(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 )

ここに私のタイミングがあります:

function      average, s  min, s   ratio
rawincount        0.0043  0.0041   1.00
rawgencount       0.0044  0.0042   1.01
rawcount          0.0048  0.0045   1.09
bufcount          0.008   0.0068   1.64
wccount           0.01    0.0097   2.35
itercount         0.014   0.014    3.41
opcount           0.02    0.02     4.83
kylecount         0.021   0.021    5.05
simplecount       0.022   0.022    5.25
mapcount          0.037   0.031    7.46

20
私は100Gb +ファイルで作業しており、あなたのrawgencountsは私がこれまで見てきた唯一の実現可能なソリューションです。ありがとう!
soungalo 2015年

1
あるwccountサブプロセスのシェルについては、この表のwcツール?
エントロピー2015

1
別のコメントでこれを見つけた、それはgist.github.com/zed/0ac760859e614cd03652
Anentropic 2015

3
@ michael-baconに感謝します、それは本当に素晴らしい解決策です。とを組み合わせる代わりに、をrawincount使用することで、ソリューションの見た目をおかしくすることができます。bufgen = iter(partial(f.raw.read, 1024*1024), b'')takewhilerepeat
Peter H.

1
ああ、部分的な機能です。ええ、それはちょっとした微調整です。また、1024 * 1024はインタープリターによってマージされ、定数として扱われると想定していましたが、ドキュメントではありませんでした。
Michael Bacon

90

サブプロセスを実行して実行できます wc -l filename

import subprocess

def file_len(fname):
    p = subprocess.Popen(['wc', '-l', fname], stdout=subprocess.PIPE, 
                                              stderr=subprocess.PIPE)
    result, err = p.communicate()
    if p.returncode != 0:
        raise IOError(err)
    return int(result.strip().split()[0])

6
これのWindowsバージョンは何でしょうか?
SilentGhost 2009年

1
これについては、このSOの質問を参照してください。stackoverflow.com/questions/247234/...
オラフルWaage

7
実際、私の場合(Mac OS X)、「for x in file(...)」が生成する行数をカウントするのに0.53秒ではなく0.13秒かかります。これに対して、str.findまたはmmap.findへの繰り返し呼び出しをカウントするのは1.0秒です。 。(これをテストするために使用したファイルには130万行あります。)
2009年

1
その上でシェルを関与させる必要はありません。回答を編集してサンプルコードを追加しました。
nosklo 2009年

2
クロスプラットフォームではありません。
e-info128 2017

42

マルチプロセッシングライブラリを使用して、マシン/コア間で行カウントを分散するpythonプログラムを次に示します。私のテストでは、8コアのWindows 64サーバーを使用して、2000万行のファイルのカウントを26秒から7秒に改善しています。注:メモリマッピングを使用しないと、処理が非常に遅くなります。

import multiprocessing, sys, time, os, mmap
import logging, logging.handlers

def init_logger(pid):
    console_format = 'P{0} %(levelname)s %(message)s'.format(pid)
    logger = logging.getLogger()  # New logger at root level
    logger.setLevel( logging.INFO )
    logger.handlers.append( logging.StreamHandler() )
    logger.handlers[0].setFormatter( logging.Formatter( console_format, '%d/%m/%y %H:%M:%S' ) )

def getFileLineCount( queues, pid, processes, file1 ):
    init_logger(pid)
    logging.info( 'start' )

    physical_file = open(file1, "r")
    #  mmap.mmap(fileno, length[, tagname[, access[, offset]]]

    m1 = mmap.mmap( physical_file.fileno(), 0, access=mmap.ACCESS_READ )

    #work out file size to divide up line counting

    fSize = os.stat(file1).st_size
    chunk = (fSize / processes) + 1

    lines = 0

    #get where I start and stop
    _seedStart = chunk * (pid)
    _seekEnd = chunk * (pid+1)
    seekStart = int(_seedStart)
    seekEnd = int(_seekEnd)

    if seekEnd < int(_seekEnd + 1):
        seekEnd += 1

    if _seedStart < int(seekStart + 1):
        seekStart += 1

    if seekEnd > fSize:
        seekEnd = fSize

    #find where to start
    if pid > 0:
        m1.seek( seekStart )
        #read next line
        l1 = m1.readline()  # need to use readline with memory mapped files
        seekStart = m1.tell()

    #tell previous rank my seek start to make their seek end

    if pid > 0:
        queues[pid-1].put( seekStart )
    if pid < processes-1:
        seekEnd = queues[pid].get()

    m1.seek( seekStart )
    l1 = m1.readline()

    while len(l1) > 0:
        lines += 1
        l1 = m1.readline()
        if m1.tell() > seekEnd or len(l1) == 0:
            break

    logging.info( 'done' )
    # add up the results
    if pid == 0:
        for p in range(1,processes):
            lines += queues[0].get()
        queues[0].put(lines) # the total lines counted
    else:
        queues[0].put(lines)

    m1.close()
    physical_file.close()

if __name__ == '__main__':
    init_logger( 'main' )
    if len(sys.argv) > 1:
        file_name = sys.argv[1]
    else:
        logging.fatal( 'parameters required: file-name [processes]' )
        exit()

    t = time.time()
    processes = multiprocessing.cpu_count()
    if len(sys.argv) > 2:
        processes = int(sys.argv[2])
    queues=[] # a queue for each process
    for pid in range(processes):
        queues.append( multiprocessing.Queue() )
    jobs=[]
    prev_pipe = 0
    for pid in range(processes):
        p = multiprocessing.Process( target = getFileLineCount, args=(queues, pid, processes, file_name,) )
        p.start()
        jobs.append(p)

    jobs[0].join() #wait for counting to finish
    lines = queues[0].get()

    logging.info( 'finished {} Lines:{}'.format( time.time() - t, lines ) )

これはメインメモリよりもはるかに大きなファイルでどのように機能しますか?たとえば、4 GBのRAMと2つのコアを備えたシステム上の20 GBのファイル
Brian Minton 2014

今はテストするのは難しいですが、ファイルのページインとページアウトができると思います。
Martlark、2014

5
これはかなりきちんとしたコードです。複数のプロセッサを使用する方が高速であることに驚きました。IOがボトルネックになると考えました。古いバージョンのPythonでは、21行目にchunk = int((fSize / processes))+ 1のようなint()が必要です
Karl Henselin

それはすべてのファイルをメモリにロードしますか?サイズがコンピュータのRAMよりも大きい、大きな火はどうですか?
ペロ

ファイルは仮想メモリにマッピングされるため、ファイルのサイズと実際のメモリの量は通常制限されません。
Martlark、2018

17

この回答に似た1行のbashソリューションで、モダンsubprocess.check_output関数を使用します。

def line_count(filename):
    return int(subprocess.check_output(['wc', '-l', filename]).split()[0])

この回答は、このスレッドでLinux / Unixユーザーの上位に投票する必要があります。クロスプラットフォームソリューションの設定の大多数にもかかわらず、これはLinux / Unixでの優れた方法です。データをサンプリングする必要がある1億8400万行のcsvファイルの場合、最高のランタイムを提供します。他の純粋なpythonソリューションでは、平均で100秒以上wc -lかかりますが、サブプロセスの呼び出しには5秒ほどかかります。
Shan Dou

shell=Trueセキュリティに悪影響があるため、回避することをお勧めします。
Alexey Vazhnov

フェアポイント、編集済み
1

15

readlines次のように、Pythonのファイルオブジェクトメソッドを使用します。

with open(input_file) as foo:
    lines = len(foo.readlines())

これにより、ファイルが開き、ファイルの行のリストが作成され、リストの長さがカウントされ、変数に保存されて、ファイルが再び閉じます。


6
これは頭​​に浮かぶ最初の方法の1つですが、特に10 GBまでのファイルの行をカウントする場合(私と同じように)、これは特にメモリの効率が悪いため、注目に値する欠点です。
SteenSchütt2014

@TimeSheepこれは、小さな行が多数(たとえば、数十億)あるファイル、または極端に長い行(たとえば、1行あたりのギガバイト)を持つファイルの問題ですか?
robert

私が尋ねる理由は、コンパイラが中間リストを作成しないことによってこれを離れて最適化できるはずだということです。
ロバート

@dmityugov Pythonドキュメントごとにxreadlines、反復子を返すだけなので、2.3以降非推奨になりました。 for line in file記載されている代替品です。参照:docs.python.org/2/library/stdtypes.html#file.xreadlines
Kumba

12
def file_len(full_path):
  """ Count number of lines in a file."""
  f = open(full_path)
  nr_of_lines = sum(1 for line in f)
  f.close()
  return nr_of_lines

12

これが私が使っているもので、かなりきれいに見えます:

import subprocess

def count_file_lines(file_path):
    """
    Counts the number of lines in a file using wc utility.
    :param file_path: path to file
    :return: int, no of lines
    """
    num = subprocess.check_output(['wc', '-l', file_path])
    num = num.split(' ')
    return int(num[0])

更新:これは純粋なpythonを使用するよりもわずかに高速ですが、メモリ使用量が犠牲になります。サブプロセスは、コマンドの実行中に、親プロセスと同じメモリフットプリントで新しいプロセスをフォークします。


1
余談ですが、これはもちろんWindowsでは機能しません。
Bram Vanroy

コアutilsは明らかにwindows用の「wc」を提供しますstackoverflow.com/questions/247234/…。コードが最終的にLinuxの製品で実行される場合は、WindowsボックスでLinux VMを使用することもできます。
radtek、

または、WSLは、このようなことが唯一の方法である場合は、どのVMよりも強く推奨されます。:-)
Bram Vanroy

そうだね。私はWindowsの人ではありませんが、グーグルからWSL = Linux用のWindowsサブシステム=)を学びました
radtek

3
python3.7:サブプロセスはバイトを返すため、コードは次のようになります:int(subprocess.check_output(['wc'、 '-l'、file_path])。decode( "utf-8")。lstrip()。split( " ")[0])
Alexey Alexeenka

11

これは、純粋なpythonを使用して見つけた最速のものです。バッファを設定することで、必要なメモリ量を使用できますが、私のコンピュータでは2 ** 16がスイートスポットのようです。

from functools import partial

buffer=2**16
with open(myfile) as f:
        print sum(x.count('\n') for x in iter(partial(f.read,buffer), ''))

ここで答えを見つけましたC ++でstdinからの行の読み取りがPythonよりもはるかに遅いのはなぜですか?ほんの少し微調整しました。行数をすばやくカウントする方法を理解するのに非常に役立ちますが、wc -l他のものよりも約75%高速です。


9

このバージョンでは定数バッファを再利用するため、メモリが少しも(GCも)オーバーヘッドを回避できるように、少し(4〜8%)改善されています。

lines = 0
buffer = bytearray(2048)
with open(filename) as f:
  while f.readinto(buffer) > 0:
      lines += buffer.count('\n')

バッファサイズをいじってみると、少し改善されるかもしれません。


いいね。\ nで終わらないファイルを説明するには、ループの外側に1を追加しますif buffer and buffer [-1]!= '\ n'
ryuusenshi

バグ:最終ラウンドのバッファーがクリーンでない可能性があります。
Jay 14年

バッファの間にある部分が\で終わり、他の部分がnで始まる場合はどうなりますか?そこに新しい行が1行ない場合、各チャンクの終了と開始を格納するために変数を使用しますが、スクリプトにさらに時間を追加する可能性があります=(
pelos

9

カイルの答え

num_lines = sum(1 for line in open('my_file.txt'))

おそらく最高ですが、これの代替策は

num_lines =  len(open('my_file.txt').read().splitlines())

これは両方のパフォーマンスの比較です

In [20]: timeit sum(1 for line in open('Charts.ipynb'))
100000 loops, best of 3: 9.79 µs per loop

In [21]: timeit len(open('Charts.ipynb').read().splitlines())
100000 loops, best of 3: 12 µs per loop

9

1行のソリューション:

import os
os.system("wc -l  filename")  

私のスニペット:

>>> os.system('wc -l *.txt')

0 bar.txt
1000 command.txt
3 test_file.txt
1003 total

残念ながら、これはWindowsでは機能しません。
Kim

3
Pythonのサーファーになりたい場合は、Windowsに別れを告げてください。いつか私に感謝します。
TheExorcist 2017年

6
これがWindowsでのみ機能することは注目に値します。私自身はlinux / unixスタックで作業することを好みますが、ソフトウェアのIMHOを作成するときは、プログラムをさまざまなOSで実行した場合の副作用を考慮する必要があります。OPが彼のプラットフォームについて言及していなかったため、誰かがgoogleを介してこのソリューションにアクセスし、それをコピーした場合(Windowsシステムの制限を意識せず)、メモを追加したかった。
キム

os.system()とにかく、出力を変数に保存して後処理することはできません。
An Se

@AnSeあなたは正しいですが、それが節約できるかどうかは質問されません。コンテキストを理解していると思います。
TheExorcist

6

上記の方法を完了するために、fileinputモジュールでバリアントを試しました:

import fileinput as fi   
def filecount(fname):
        for line in fi.input(fname):
            pass
        return fi.lineno()

そして60mil linesファイルを上記のすべてのメソッドに渡しました:

mapcount : 6.1331050396
simplecount : 4.588793993
opcount : 4.42918205261
filecount : 43.2780818939
bufcount : 0.170812129974

ファイル入力が他のすべての方法よりも悪く、スケーリングがはるかに悪いのは少し驚きです...


5

私にとっては、このバリアントが最速になります:

#!/usr/bin/env python

def main():
    f = open('filename')                  
    lines = 0
    buf_size = 1024 * 1024
    read_f = f.read # loop optimization

    buf = read_f(buf_size)
    while buf:
        lines += buf.count('\n')
        buf = read_f(buf_size)

    print lines

if __name__ == '__main__':
    main()

理由:行ごとに読み取るよりもバッファリングが速く、string.countまた非常に速い


1
しかし、そうですか?少なくともOSX / python2.5では、timeit.pyによると、OPのバージョンは依然として約10%高速です。
dF。

最後の行が「\ n」で終わっていない場合はどうなりますか?
tzot 2009年

1
どのようにテストしたかはわかりませんが、私のマシンでは、他のどのオプションよりも約2.5倍遅いです。
SilentGhost 2009年

34
あなたはそれが最速であると述べ、それからあなたはそれをテストしていないと述べます。あまり科学的ではありませんか?:)
オラフルWaage

以下のRyan Ginstromの回答が提供するソリューションと統計を参照してください。また、JF Sebastianのコメントをチェックして、同じ回答にリンクしてください。
SherylHohman 2017年

5

このコードは短くて明確です。それはおそらく最良の方法です:

num_lines = open('yourfile.ext').read().count('\n')

6
ファイルも閉じる必要があります。
rsm

6
ファイル全体をメモリにロードします。
イベリン

大きなファイルのパフォーマンスが必要な場合は最適ではありません
マブラハム

4

私はこのようにバッファーケースを変更しました:

def CountLines(filename):
    f = open(filename)
    try:
        lines = 1
        buf_size = 1024 * 1024
        read_f = f.read # loop optimization
        buf = read_f(buf_size)

        # Empty file
        if not buf:
            return 0

        while buf:
            lines += buf.count('\n')
            buf = read_f(buf_size)

        return lines
    finally:
        f.close()

空のファイルと最後の行(\ nなし)もカウントされるようになりました。


また、変更点と変更点についても説明します(またはコードにコメントを追加します)。(脳内でコードを「解析」するのではなく)、コード内のより多くの部分を人々にもっと簡単に与えるかもしれません。
Styxxy

ループの最適化により、Pythonはread_f、python.org / doc
The Red Pea

3

これはどうですか

def file_len(fname):
  counts = itertools.count()
  with open(fname) as f: 
    for _ in f: counts.next()
  return counts.next()



3
def line_count(path):
    count = 0
    with open(path) as lines:
        for count, l in enumerate(lines, start=1):
            pass
    return count

3

LinuxのPythonで安価に行数を取得したい場合は、この方法をお勧めします。

import os
print os.popen("wc -l file_path").readline().split()[0]

file_pathは、抽象ファイルパスまたは相対パスの両方にすることができます。これが役立つことを願っています。


2

これはどう?

import fileinput
import sys

counter=0
for line in fileinput.input([sys.argv[1]]):
    counter+=1

fileinput.close()
print counter

2

このワンライナーはどうですか:

file_length = len(open('myfile.txt','r').read().split('\n'))

この方法を使用して3900行のファイルで時間を計るには、0.003秒かかります

def c():
  import time
  s = time.time()
  file_length = len(open('myfile.txt','r').read().split('\n'))
  print time.time() - s

2
def count_text_file_lines(path):
    with open(path, 'rt') as file:
        line_count = sum(1 for _line in file)
    return line_count

それが間違っていると思われる場合、何が悪いのか説明してもらえますか?それは私のために働いた。ありがとう!
jciloa 2017

この回答がなぜ反対票だったのかに興味があります。それは行ごとにファイルを反復処理し、それらを合計します。私はそれが好きです、それは短く、要点として、それの何が問題になっていますか?
2018年

2

簡単な方法:

1)

>>> f = len(open("myfile.txt").readlines())
>>> f

430

2)

>>> f = open("myfile.txt").read().count('\n')
>>> f
430
>>>

3)

num_lines = len(list(open('myfile.txt')))

3
この例では、ファイルは閉じられていません。
Maciej M

9
OPはメモリ効率の良いものを求めていました。これは間違いなくそうではありません。
アンディカールソン

1

ファイルを開いた結果はイテレータで、これは長さを持つシーケンスに変換できます。

with open(filename) as f:
   return len(list(f))

これは明示的なループよりも簡潔で、を回避しenumerateます。


10
つまり、100 Mbファイルをメモリに読み込む必要があります。
SilentGhost 2009年

ええ、良い点ですが、(メモリではなく)速度の違いについては疑問です。これを行うイテレータを作成することはおそらく可能ですが、私はそれがあなたの解決策と同等になると思います。
Andrew Jaffe

6
-1、それは単なるメモリではなく、メモリ内にリストを作成する必要があります。
orip 2009

0

os.path次の方法でモジュールを使用できます。

import os
import subprocess
Number_lines = int( (subprocess.Popen( 'wc -l {0}'.format( Filename ), shell=True, stdout=subprocess.PIPE).stdout).readlines()[0].split()[0] )

ここFilenameで、はファイルの絶対パスです。


1
この答えは何と関係がありos.pathますか?
moi 2017

0

ファイルがメモリに収まる場合は、

with open(fname) as f:
    count = len(f.read().split(b'\n')) - 1
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.