Как дешево получить количество строк в большом файле в Python?

Мне нужно получить количество строк в большом файле (сотни тысяч строк) в python. Каков наиболее эффективный способ как по памяти, так и по времени?

На данный момент я делаю:

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

можно ли сделать что-нибудь лучше?


Лучше этого не найти.

В конце концов, любое решение должно будет прочитать файл целиком, выяснить, сколько n у вас есть, и вернуть этот результат.

Есть ли у вас лучший способ сделать это, не читая весь файл? Не уверен … Лучшее решение всегда будет с привязкой к вводу-выводу, лучшее, что вы можете сделать, это убедиться, что вы не используете ненужную память, но похоже, что у вас это покрыто.


Одна строка, вероятно, довольно быстро:

  num_lines = sum (1 для открытой строки  ('myfile.txt'))  


Одна строка, вероятно, довольно быстро:

  num_lines = sum (1 для строки в open ('myfile.txt'))  

Я считаю, что файл с отображением памяти будет самым быстрым решением. Я пробовал четыре функции: функцию, отправленную OP ( opcount ); простой перебор строк в файле ( simplecount ); строка чтения с полем с отображением памяти (mmap) ( mapcount ); и решение для чтения буфера, предложенное Николаем Харечко ( bufcount ).

Я запускал каждую функцию пять раз и вычислял среднее время выполнения для 1,2 миллиона строковый текстовый файл.

Windows XP, Python 2.5, 2 ГБ ОЗУ, процессор AMD 2 ГГц

Вот мои результаты:

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

Изменить : числа для Python 2.6:

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

Таким образом, стратегия чтения из буфера кажется самой быстрой для Windows/Python 2.6

Вот код:

  из __future__ import with_statementimport timeimport mmapimport randomfrom collection import defaultdictdef mapcount (filename): f = open (filename, "r +  ") buf = mmap.mmap (f.fileno (), 0) lines = 0 readline = buf.readline while readline (): lines + = 1 return linesdef simple  count (filename): lines = 0 для строки в open (filename): lines + = 1 return linesdef bufcount (filename): f = open (filename) lines = 0 buf_size = 1024 * 1024 read_f = f.read # оптимизация цикла buf  = read_f (buf_size), а buf: lines + = buf.count (' n') buf = read_f (buf_size) return linesdef opcount (fname): with open (fname) as f: for i, l in enumerate (f)  : pass return i + 1counts = 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) для ключа, vals в counts.items (): print key .__ name__, ":",  sum (vals)/float (len (vals))  


Я считаю, что файл с отображением памяти будет самым быстрым решением. Я пробовал четыре функции: функцию, отправленную OP ( opcount ); простой перебор строк в файле ( simplecount ); строка чтения с полем с отображением памяти (mmap) ( mapcount ); и решение для чтения буфера, предложенное Николаем Харечко ( bufcount ).

Я запускал каждую функцию пять раз и вычислял среднее время выполнения для 1,2 миллиона строковый текстовый файл.

Windows XP, Python 2.5, 2 ГБ ОЗУ, процессор AMD 2 ГГц

Вот мои результаты:

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

Изменить : числа для Python 2.6:

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

Таким образом, стратегия чтения из буфера кажется самой быстрой для Windows/Python 2.6

Вот код:

  из __future__ import with_statementimport timeimport mmapimport randomfrom collection import defaultdictdef mapcount (filename): f = open (filename, "r +  ") buf = mmap.mmap (f.fileno (), 0) lines = 0 readline = buf.readline while readline (): lines + = 1 return linesdef simple  count (filename): lines = 0 для строки в open (filename): lines + = 1 return linesdef bufcount (filename): f = open (filename) lines = 0 buf_size = 1024 * 1024 read_f = f.read # оптимизация цикла buf  = read_f (buf_size), а buf: lines + = buf.count (' n') buf = read_f (buf_size) return linesdef opcount (fname): with open (fname) as f: for i, l in enumerate (f)  : pass return i + 1counts = 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) для ключа, vals в counts.items (): print key .__ name__, ":", sum (vals)/float (len (vals))  

Мне пришлось публиковать это по аналогичному вопросу, пока мой рейтинг репутации немного не подскочил (спасибо кто бы меня ни ударил!).

Все эти решения игнорируют один способ сделать это значительно быстрее, а именно, используя небуферизованный (необработанный) интерфейс, используя массивы байтов и выполняя собственную буферизацию. (Это применимо только в Python 3. В Python 2 необработанный интерфейс может использоваться или не использоваться по умолчанию, но в Python 3 по умолчанию используется Unicode.. )

Используя модифицированную версию инструмента синхронизации, я считаю, что следующий код быстрее (и немного более питоничен), чем любое из предлагаемых решений:

  def rawcount (filename): f = open (filename, 'rb') lines = 0 buf_size = 1024 * 1024 read_f = f.raw.read buf = read_f (buf_size), а buf: lines + = buf.count (  b ' n') buf = read_f (buf_size) возвращаемые строки  

При использовании отдельной функции генератора это работает немного быстрее:

  def _make_gen (reader): b = reader (1024 * 1024), а b: yield bb = 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) для _ в повторе  t (None))) return sum (buf.count (b ' n') for buf in bufgen)  

Вот мои тайминги:

  функция среднее, с мин, с отношение  0,037 0,031 7,46  


Мне пришлось публиковать это по аналогичному вопросу, пока моя репутация не набрала немного подпрыгнул (спасибо, кто меня толкнул!).

Все эти решения игнорируют один способ сделать это значительно быстрее, а именно, используя небуферизованный (необработанный) интерфейс, используя массивы байтов и выполняя собственную буферизацию. (Это применимо только в Python 3. В Python 2 необработанный интерфейс может использоваться или не использоваться по умолчанию, но в Python 3 по умолчанию используется Unicode.)

Использование измененной версии инструмента синхронизации, я считаю, что следующий код быстрее (и немного более питоничен), чем любое из предлагаемых решений:

  def rawcount (filename): f = open (filename  , 'rb') lines = 0 buf_size = 1024 * 1024 read_f = f.raw.read buf = read_f (buf_size) в то время как buf: lines + = buf.count (b ' n') buf = read_f (buf_size) возвращаемые строки   

При использовании отдельной функции генератора это выполняется немного быстрее:

  def _make_gen (reader): b = reader (1024  * 1024) в то время как b: yield bb = reader (1024 * 1024) def rawgencount (filename): f = open (filename, 'rb') f_gen = _make_gen (f.raw.read) return sum (buf. count (b ' n') для buf в 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) для _ в повторении (Нет))) вернуть сумму (buf.count (b ' n') для buf в bufgen)  

Вот мои тайминги:

  среднее значение функции, s min, s ratiorawincount 0,0043 0,0041 1,00rawgencount 0,0044 0,0042 1,01rawcount 0,0048 0,0045 1,09bufcount 0,008 0,0068 1,64wccount 0,01 0,0097 2,35itercount 0,014 0,014 3,41opcount 0,02 0,02 4,83kylecount  0,021 0,021 5,05simplecount 0,022 0,022 5,25mapcount 0,037 0,031 7,46  

Вы можете выполнить подпроцесс и запустите wc -l filename

  import subprocessdef file_len (fname): p = subprocess.Popen (['wc', '-l'  , fname], stdout = subprocess.PIPE, stderr = s  ubprocess.PIPE) result, err = p.communicate () if p.returncode! = 0: поднять IOError (err) return int (result.strip (). split () [0])  


Вы можете выполнить подпроцесс и запустить wc -l filename

  import subprocessdef file_len (fname): p = subprocess.Popen (['wc', '-l', fname], stdout = subprocess.PIPE, stderr = subprocess.PIPE) result,  err = p.communicate () if p.returncode! = 0: поднять IOError (err) return int (result.strip (). split () [0])  

Вот программа на Python, которая использует многопроцессорную библиотеку для распределения подсчета строк по машинам/ядрам. Мой тест улучшает подсчет файла с 20 миллионами строк с 26 до 7 секунд с использованием 8-ядерного сервера Windows 64. Примечание: отказ от использования отображения памяти значительно замедляет работу.

  import multiprocessing, sys, time, os, mmapimport logging, logging.handlersdef init_logger (pid): console_format = 'P {  0}% (levelname) s% (message) s'.format (pid) logger = logging.getLogger () # Новый регистратор на корневом уровне 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 (очереди, pid, процессы, 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) # определить размер файла для разделения подсчета строк fSize = os.stat (file1). st_size chunk = (fSize/process) + 1 lines = 0 # получить, где я запускаю и останавливаю _seedStart = chunk * (pid) _seekEnd = chunk * (pid + 1) seekStart = int (_seedStart) seekEnd = int (_seekEnd) if seekEnd   fSize: seekEnd = fSize # найти, с чего начать, если pid> 0: m1.seek (seekStart)  # прочитать следующую строку l1 = m1.readline () # необходимо использовать строку чтения с файлами с отображением в памяти seekStart = m1.tell () # указать предыдущий ранг моего начала поиска, чтобы их поиск закончился, если pid> 0: queues [pid-1]  .put (seekStart), если pid  0: lines + = 1 l1 = m1  .readline () if m1.tell ()> seekEnd или len (l1) == 0: break logging.info ('done') # складываем результаты, если pid == 0: для p в диапазоне (1, процессы)  : lines + = queues [0] .get () queues [0] .put (lines) # общее количество строк, подсчитанных 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 (' необходимые параметры: имя-файла [процессы] ') exit () t =  time.time () процессы = multiprocessing.cpu_count () если len (sys.argv)> 2: процессы = int (sys.argv [2]) queues = [] # очередь для каждого процесса для pid в диапазоне (процессы)  : queues.append (multiprocessing.Queue ()) jobs = [] prev_pipe = 0 для pid в диапазоне (процессы): p = multiprocessing.Process (target = getFileLineCount, args = (queues, pid ,cesses, file_name,)) p  .start () jobs.append (p) jobs [0] .join () # ждать подсчета до финиша строк = queues [0] .get () logging.info ('finished {} Lines: {}'. format (  time.time () - t, строки))  


Вот программа на Python использовать многопроцессорную библиотеку для распределения подсчета строк по машинам/ядрам. Мой тест улучшает подсчет файла с 20 миллионами строк с 26 до 7 секунд с использованием 8-ядерного сервера Windows 64. Примечание: отказ от использования отображения памяти значительно замедляет работу.

  import multiprocessing, sys, time, os, mmapimport logging, logging.handlersdef init_logger (pid): console_format = 'P {  0}% (levelname) s% (message) s'.format (pid) logger = logging.getLogger () # Новый регистратор на корневом уровне 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 (очереди, pid, процессы, 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) # определить размер файла для разделения подсчета строк fSize = os.stat (file1). st_size chunk = (fSize/process) + 1 lines = 0 # получить, где я запускаю и останавливаю _seedStart = chunk * (pid) _seekEnd = chunk * (pid + 1) seekStart = int (_seedStart) seekEnd = int (_seekEnd) if seekEnd   fSize: seekEnd = fSize # найти, с чего начать, если pid> 0: m1.seek (seekStart)  # прочитать следующую строку l1 = m1.readline () # необходимо использовать строку чтения с файлами с отображением в памяти seekStart = m1.tell () # указать предыдущий ранг моего начала поиска, чтобы их поиск закончился, если pid> 0: queues [pid-1]  .put (seekStart), если pid  0: lines + = 1 l1 = m1  .readline () if m1.tell ()> seekEnd или len (l1) == 0: break logging.info ('done') # складываем результаты, если pid == 0: для p в диапазоне (1, процессы)  : lines + = queues [0] .get () queues [0] .put (lines) # общее количество строк, подсчитанных 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 (' необходимые параметры: имя-файла [процессы] ') exit () t =  time.time () процессы = multiprocessing.cpu_count () если len (sys.argv)> 2: процессы = int (sys.argv [2]) queues = [] # очередь для каждого процесса для pid в диапазоне (процессы)  : queues.append (multiprocessing.Queue ()) jobs = [] prev_pipe = 0 для pid в диапазоне (процессы): p = multiprocessing.Process (target = getFileLineCount, args = (queues, pid ,cesses, file_name,)) p  .start () jobs.append (p) jobs [0] .join () # ждать подсчета до финиша строк = queues [0] .get () logging.info ('finished {} Lines: {}'. format (  time.time () - t, lines))  

Однострочное решение bash аналогично этому ответу, используя современную функцию subprocess.check_output :

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


Однострочное решение bash, подобное этому ответу, с использованием современной функции subprocess.check_output :

  def line_count  (имя файла): return int (subprocess.check_output (['wc', '-l', filename]). split () [0])  

Я бы использовал метод файлового объекта Python readlines следующим образом:

   с open (input_file) как foo: lines = len (foo.readlines ())  

Это открывает файл, создает список строк в файле, подсчитывает длину list, сохраняет это в переменной и снова закрывает файл.


Я бы использовал метод файлового объекта Python readlines следующим образом:

  с open (input_file) как foo: lines = len (foo.readlines ())  

Это открывает файл, создает список строк в файле , считает длину списка, сохраняет ее в переменной и снова закрывает файл.


Это Самая быстрая вещь, которую я нашел, используя чистый питон. Вы можете использовать любой объем памяти, который хотите, установив буфер, хотя 2 ** 16, похоже, является приятным местом на моем компьютере.

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

Я нашел ответ здесь Почему чтение строк из stdin намного медленнее в C ++, чем в Python? и немного подправили. Это очень хорошее чтение, чтобы понять, как быстро подсчитывать строки, хотя wc -l все еще примерно на 75% быстрее, чем что-либо еще.


Это самая быстрая вещь, которую я нашел с использованием чистого Python. Вы можете использовать любой объем памяти, который хотите, установив буфер, хотя 2 ** 16 выглядит как сладкое пятно на моем компьютере.

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

Я нашел здесь ответ. Почему чтение строк из стандартного ввода намного медленнее в C ++, чем в Python? и немного подправили. Это очень хорошее чтение, чтобы понять, как быстро подсчитывать строки, хотя wc -l все еще примерно на 75% быстрее, чем что-либо еще.


  def file_len (full_path): "" "Подсчитать количество строк в файле." "" f = open (full_path) nr_of_lines = sum (  1 для строки в f) f.close () return nr_of_lines  


  def file_len (full_path): "  "" Подсчитать количество строк в файле. "" "F = open (full_path) nr_of_lines = sum (1 для строки в f) f.close () return nr_of_lines  

Вот то, что я использую, кажется довольно чистым:

  import subprocessdef count_file_lines (file_path):  "" "Подсчитывает количество строк в файле с помощью утилиты wc.: Param file_path: путь к файлу: return: int, no of lines" "" num = subprocess.check_output (['wc', '-l', file_path  ]) num = num.split ('') return int (num [0])  

ОБНОВЛЕНИЕ: это немного быстрее, чем использование чистого Python, но за счет использования памяти. Подпроцесс будет разветвлять новый процесс с тем же объемом памяти, что и родительский процесс, пока он выполняет вашу команду.


Вот то, что я использую, кажется довольно чистым:

  import subprocessdef count_file_lines (file_path): "" "Подсчитывает количество строк в файле с помощью утилиты wc.: param file_path: путь к файлу: return: int, no of lines" "" num = subprocess.check_output (  ['wc', '-l', file_path]) num = num.split ('') return int (num [0])  

ОБНОВЛЕНИЕ: это немного быстрее, чем используя чистый питон, но за счет использования памяти. Подпроцесс будет разветвлять новый процесс с тем же объемом памяти, что и родительский процесс, пока он выполняет вашу команду.


Однострочное решение:

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

Мой фрагмент:

 >>> os.system ('wc -l * .txt') 0 bar.txt1000 command.txt3 test_file.txt1003 total  


Однострочное решение:

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

Мой фрагмент:

 >>> os.system ('wc -l * .txt') 0 bar.  txt1000 command.txt3 test_file.txt1003 total  

Я получил небольшой (4-8% ) улучшение с этой версией, которая повторно использует постоянный буфер, поэтому он должен избегать каких-либо накладных расходов на память или сборщик мусора:

  lines = 0buffer = bytearray (2048) with open (filename) as  f: в то время как f.readinto (буфер)> 0: строки + = buffer.count  (' n')  

Вы можете поиграть с размером буфера и, возможно, увидите небольшое улучшение.


Я получил небольшое (4-8%) улучшение с этой версией, которая повторно использует постоянный буфер, поэтому он должен избегать каких-либо накладных расходов на память или сборщик мусора:

   lines = 0buffer = bytearray (2048) с open (filename) как f: while f.readinto (buffer)> 0: lines + = buffer.count (' n')  

Вы можете поиграть с размером буфера и, возможно, увидите небольшое улучшение.


Ответ Кайла

  num_lines = sum (1 для строки в open ('my_file.txt'))  

, вероятно, лучше всего, альтернативой для этого является

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

Вот сравнение производительности обоих

  В [20]: timeit sum (1 для открытой строки ('Charts.ipynb')) 100000 циклов, лучшее из 3: 9,79 мкс  на loopIn [21]: timeit len ​​(open ('Charts.ipynb'). read (). splitlines ()) 100000 циклов, лучшее из 3: 12 мкс на цикл  


Кайла answer

  num_lines = sum (1 для строки в open ('my_file.txt'))  

, вероятно, лучше всего, альтернативой для этого является

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

Вот сравнение производительности обоих

  В [20]: timeit sum (1 для открытой строки ('Charts.ipynb')) 100000 циклов, лучший из  3: 9,79 мкс на циклIn [21]: timeit len ​​(open ('Charts.ipynb'). Read (). Splitlines ()) 100000 циклов, лучшее из 3: 12 мкс на цикл  

Чтобы завершить описанные выше методы, я попробовал вариант с модулем ввода файла:

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

И передал 60миллионный файл строк в все вышеперечисленные характеристики ed методы:

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

Это небольшой сюрприз для мне, что fileinput настолько плох и масштабируется намного хуже, чем все другие методы …


Просто чтобы завершить описанные выше методы, я попробовал вариант с модуль fileinput:

  импортировать fileinput как fi def filecount (fname): для строки в fi.input (fname): pass return fi.lineno ()  

И передал файл 60 мил строк всем вышеуказанным методам:

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

Для меня немного удивительно, что fileinput настолько плох и масштабируется намного хуже, чем все другие методы …


Как по мне, этот вариант будет самый быстрый:

  #!/usr/bin/env pythondef main (): f = open ('filename') lines = 0 buf_size = 1024 * 1024 read_f = f.read  # оптимизация цикла buf = read_f (buf_size) while buf: lines + = buf.count (' n') buf = read_f (buf_size) print linesif __name__ == '__main__': main ()  

причины: буферизация быстрее, чем чтение построчно, и string.count тоже очень быстро


Как по мне, этот вариант будет самым быстрым:

  #!/usr/bin/env pythondef main (): f =  open ('filename') lines = 0 buf_size = 1024 * 1024 read_f = f.read # оптимизация цикла buf = read_f (buf_size) while buf: lines + = buf. count (' n') buf = read_f (buf_size) print linesif __name__ == '__main__': main ()  

Причины: буферизация быстрее, чем чтение построчно и string.count тоже очень быстрый


Я изменил регистр буфера, например это:

  def CountLines (filename): f = open (filename) try: lines = 1 buf_size = 1024 * 1024 read_f = f.read # оптимизация цикла buf = read_f (  buf_size) # Пустой файл, если не buf: вернуть 0, а buf: lines + = buf.count (' n') buf = read_f (buf_size) наконец вернуть строки: f.close ()  

Теперь также подсчитываются пустые файлы и последняя строка (без n).


Я изменил корпус буфера следующим образом:

  def CountLines (filename): f = open (filename) try: lines = 1 buf_size = 1024 * 1024 read_f = f.read # оптимизация цикла buf = read_f (buf_size)  # Пустой файл, если не buf: вернуть 0, пока  buf: lines + = buf.count (' n') buf = read_f (buf_size) наконец вернут строки: f.close ()  

Теперь также пустые файлы и последняя строка (без n) считаются.


Этот код короче и понятнее. Вероятно, это лучший способ:

  num_lines = open ('yourfile.ext'). Read (). Count (' n')  


Этот код короче и понятнее. Вероятно, это лучший способ:

  num_lines = open ('yourfile.ext'). Read (). Count (' n')  

Результатом открытия файла является итератор, который можно преобразовать в последовательность, имеющую длину:

  с open (filename) как f: return len (list (f))  

это более лаконично, чем ваш явный цикл, и избегает enumerate .


результат открытия файла представляет собой итератор, который можно преобразовать в последовательность, имеющую длину:

  с open (filename) как f: return len (list (f))  

это более лаконично, чем ваш явный цикл, и позволяет избежать enumerate .


count = max (enumerate (open (filename))) [0]


count = max (enumerate (open (filename))) [0]


  print open ('file.txt', 'r'). read (). count (" n") + 1   


  печать open ('file.txt', 'r'). read (). count (" n") + 1  

  def line_count (  path): count = 0 с open (path) в виде строк: для count, l в enumerate (lines, start = 1): pass return count  


  def line_count (path): count = 0 с open (path) как строками: for count, l в enumerate (lines, start = 1): pass return count  

Если кто-то хочет дешево получить количество строк в Python в Linux, я рекомендую этот метод:

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

file_path может быть как абстрактным путем к файлу, так и относительным путем. Надеюсь, это поможет.


Если кто-то хочет получить дешевое количество строк в Python в Linux, я рекомендую этот метод:

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

file_path может быть как абстрактным, так и относительным путем. Надеюсь, это может помочь.


  def count_text_file_lines (path): with open (path,  'rt') как файл: line_count = sum (1 для _line в файле) return line_count  


  def  count_text_file_lines (path): с open (path, 'rt') as file: line_count = sum (1 для _line в файле) return line_count  

А как насчет этого

  def file_len (fname): counts = itertools.count () с open (fname) как f:  for _ в f: counts.next () return counts.next ()  


А как насчет этого

  def file_len (fname): counts = itertools.count () с open (fname) как f: for _ в f: counts.next () return counts.next ()  

Как насчет этого?

  import fi  leinputimport syscounter = 0 для строки в fileinput.input ([sys.argv [1]]): counter + = 1fileinput.close () счетчик печати  


Как насчет этого?

  import fileinputimport syscounter = 0 for line in fileinput.input ([sys.argv [1]]): counter + = 1fileinput.close ()  счетчик печати  

Как насчет этого однострочника:

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

Принимает 0,003 sec, используя этот метод для измерения времени в файле 3900 строк

  def c (): import time s = time.time () file_length = len (open ('myfile.txt  ',' r '). read (). split ('  n ')) время печати. time () - s  


Как насчет этого однострочника:

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

При использовании этого метода требуется 0,003 секунды для время его в файле 3900 строк

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

Это мета-комментарий к некоторым другим ответам.

  • Чтение строк и буферизация n методы подсчета не возвращают одинаковый ответ для каждого файла, потому что в некоторых текстовых файлах нет новой строки в конце последней строки. Вы можете обойти это, проверив последний байт последнего непустого буфера и добавив 1, если он не b'n'.

  • В Python 3 открытие файла в текстовом режиме и в двоичном режиме может дать разные результаты, поскольку текстовый режим по умолчанию распознает CR, LF и CRLF как окончания строки (преобразовывая их все в ' n '), тогда как в двоичном режиме будут учитываться только LF и CRLF, если вы подсчитаете b' n '. Это применимо независимо от того, читаете ли вы по строкам или в буфер фиксированного размера. Классическая Mac OS использовала CR как окончание строки; Я не знаю, насколько распространены эти файлы в наши дни.

  • Подход с чтением буфера использует ограниченный объем ОЗУ независимо от размера файла, в то время как строка Подход с чтением может в худшем случае прочитать весь файл в ОЗУ сразу (особенно если в файле используются окончания строки CR). В худшем случае он может использовать значительно больше ОЗУ, чем размер файла, из-за накладных расходов из-за динамического изменения размера строкового буфера и (если вы открыли в текстовом режиме) декодирования и хранения Unicode.

  • Вы можете улучшить использование памяти и, возможно, скорость буферизованного подхода, предварительно выделив массив байтов и используя readinto вместо read код>. Один из существующих ответов (с небольшим количеством голосов) делает это, но он содержит ошибки (он дважды считает некоторые байты).

  • В верхнем ответе на чтение буфера используется большой буфер (1 МиБ). Использование буфера меньшего размера может быть быстрее из-за опережающего чтения ОС. Если вы читаете 32 КБ или 64 КБ за раз, ОС, вероятно, начнет считывать следующие 32 КБ/64 КБ в кеш до того, как вы его попросите, и каждое обращение к ядру будет возвращаться почти немедленно. Если вы читаете 1 мегабайт за раз, ОС вряд ли предположительно прочитает целый мегабайт. Он может предварительно прочитать меньшее количество данных, но вы все равно проведете значительное количество времени, сидя в ядре, ожидая, пока диск вернет остальные данные.


Это мета-комментарий к некоторым другим ответам.

  • Методы чтения строк и буферизованного n -счета не вернут одинаковый ответ для каждого файла, потому что некоторые текстовые файлы не имеют новой строки в конце последней строки. Вы можете обойти это, проверив последний байт последнего непустого буфера и добавив 1, если он не b'n'.

  • В Python 3 открытие файла в текстовом режиме и в двоичном режиме может дать разные результаты, поскольку текстовый режим по умолчанию распознает CR, LF и CRLF как окончания строки (преобразовывая их все в ' n '), тогда как в двоичном режиме будут учитываться только LF и CRLF, если вы подсчитаете b' n '. Это применимо независимо от того, читаете ли вы по строкам или в буфер фиксированного размера. Классическая Mac OS использовала CR как окончание строки; Я не знаю, насколько распространены эти файлы в наши дни.

  • Подход с чтением буфера использует ограниченный объем ОЗУ независимо от размера файла, в то время как строка Подход с чтением может в худшем случае прочитать весь файл в ОЗУ сразу (особенно если в файле используются окончания строки CR). В худшем случае он может использовать значительно больше ОЗУ, чем размер файла, из-за накладных расходов из-за динамического изменения размера строкового буфера и (если вы открыли в текстовом режиме) декодирования и хранения Unicode.

  • Вы можете улучшить использование памяти и, возможно, скорость буферизованного подхода, предварительно выделив массив байтов и используя readinto вместо read код>. Один из существующих ответов (с небольшим количеством голосов) делает это, но он содержит ошибки (он дважды считает некоторые байты).

  • В верхнем ответе на чтение буфера используется большой буфер (1 МиБ). Использование буфера меньшего размера может быть быстрее из-за опережающего чтения ОС. Если вы читаете 32 КБ или 64 КБ за раз, ОС, вероятно, начнет считывать следующие 32 КБ/64 КБ в кеш до того, как вы его попросите, и каждое обращение к ядру будет возвращаться почти немедленно. Если вы читаете 1 мегабайт за раз, ОС вряд ли предположительно прочитает целый мегабайт. Он может предварительно прочитать меньшее количество данных, но вы все равно проведете значительное количество времени, сидя в ядре, ожидая, пока диск вернет остальные данные.


Почему бы не прочитать первые 100 и последние 100 строк и не оценить среднюю длину строки, а затем разделить общий размер файла на эти числа? Если вам не нужно точное значение, это может сработать.


Почему бы не прочитать первые 100 и последние 100 строк и не оценить среднюю строку length, а затем разделить общий размер файла на эти числа? Если вам не нужно точное значение, это может сработать.


Вы можете использовать os.path следующим образом:

  import osimport subprocessNumber_lines = int ((subprocess.Popen ('wc -l {0}'. format (  Имя файла), оболочка = True, stdout = subprocess.PIPE) .stdout). readlines () [0] .split () [0])  

, где Имя файла — это абсолютный путь к файлу.


Вы можете использовать модуль os.path следующим образом:

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

, где Имя файла — это абсолютный путь к файлу.

Оцените статью
techsly.ru
Добавить комментарий