2009-08-24 2 views
21

Я довольно новичок в Python, и я пытаюсь выяснить наиболее эффективный способ подсчета количества файлов .TIF в определенном подкаталоге.Подсчитайте количество файлов с определенным расширением в Python

Выполнение некоторых поисков, я нашел один пример (я не проверял), который утверждал, что рассчитывать все файлы в каталоге:

file_count = sum((len(f) for _, _, f in os.walk(myPath))) 

Это прекрасно, но мне нужно рассчитывать только TIF файлы , Мой каталог будет содержать другие типы файлов, но я хочу только подсчитать TIF.

В настоящее время я использую следующий код:

tifCounter = 0 
for root, dirs, files in os.walk(myPath): 
    for file in files:  
     if file.endswith('.tif'): 
      tifCounter += 1 

Он отлично работает, но зациклившейся кажется чрезмерным/дорого мне. Любой способ сделать это более эффективно?

Спасибо.

+0

Наиболее эффективный способ сделать вещи в Python часто, чтобы сделать их в C . :) – Imagist

+3

Что вам не нравится? Что означает «чрезмерное»? Что значит «дорого»? –

ответ

32

Что-то нужно перебирать по всем файлам в каталоге и просматривать каждое имя файла - будь то ваш код или подпрограмма библиотеки. Поэтому, независимо от конкретного решения, все они будут иметь одинаковую стоимость.

Если вы считаете, что это слишком много кода, и если вы на самом деле не нужно искать подкаталоги рекурсивно, вы можете использовать glob модуль:

tifCounter = len(glob.glob1(myPath,"*.tif")) 
+0

Спасибо. Это работало одинаково хорошо, а в 1/5 количество строк! Даже если он стоит одинаково, он выглядит красивее! :) –

+0

'glob1'? зачем использовать недокументированную функцию? почему бы не использовать 'glob.glob', который дает точно такой же результат? – SilentGhost

+1

@SilentGhost: glob.glob ожидает только один параметр, который является именем пути. В конкретном случае каталог уже доступен, поэтому сначала не нужно присоединяться к нему, так что glob может снова разбить его. Кроме того, если myPath имеет в нем символ glob, glob.glob интерпретирует его. –

4

Ваш код в порядке.

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

Я бы не стал беспокоиться об оптимизации этого кода.

2

Если вам не нужно искать рекурсивно, или для некоторых другая причина не хочет использовать glob модуль, вы можете использовать

file_count = sum(len(f for f in fs if f.lower().endswith('.tif')) for _, _, fs in os.walk(myPath)) 

Это «Pythonic» способ адаптации к примеру вы нашли для ваших целей. Но это не будет значительно быстрее или эффективнее, чем цикл, который вы использовали; это просто очень компактный синтаксис для более или менее того же.

+4

С каких пор термин «pythonic» описывает процедуру преобразования идеально читаемых 3 строк кода в одну единственную строку вложенных циклов, которая занимает как минимум в 5 раз больше времени, чтобы понять и нарушить PEP8 в процессе? –

+0

Поскольку люди делали подобные вещи в Python (и это было довольно долгое время). Но обратите внимание, что я поставил «Pythonic» в кавычки («quote-Pythonic-unquote»), потому что то, что на самом деле делается на Python и что указано в PEP 8, - это две разные вещи. –

4

Для этого конкретного случая использования, если вы не хотите, чтобы рекурсивно искать в подкаталоге, вы можете использовать os.listdir:

len([f for f in os.listdir(myPath) 
    if f.endswith('.tif') and os.path.isfile(os.path.join(myPath, f))]) 
Смежные вопросы