2014-12-10 3 views
2

У меня есть небольшой бит кода для отображения имен файлов, соответствующих строке фильтра. Я пытаюсь расширить это, чтобы соответствовать нескольким фильтрам. У меня есть какой-то рабочий код, который использует очень прямой подход в прямом цикле, но это sloooooooow .... в основном работает os.walk для каждого фильтра.Python - эффективный способ поиска имен файлов на основе нескольких фильтров

Учитывая, что функция (показана ниже) позволяет протестировать несколько фильтров одновременно, а не по одному за раз? т. е. можно ли передать список строк фильтра в find_files?

import os 
import fnmatch 

# stolen from http://stackoverflow.com/questions/8625991/use-python-os-walk-to-identify-a-list-of-files 
def find_files(dir_look, filt): 
    matches = [] 
    for root, dirnames, filenames in os.walk(dir_look): 
     for filename in fnmatch.filter(filenames, filt): 
      matches.append(os.path.join(root, filename)) 
    return matches 

#create empty list to store results 
filelist=[] 

#some example filters, my real data has about 5000 filters 
filts = [r'*60830007*',r'*60910259*',r'*60910299*'] 

#find files for each filter entry 
for filter in filts: 
    filelist.append(find_files(r'C:\some directory', filter)) 

EDIT:

я нашел довольно очевидный способ ускорить вещи, передавая список фильтров к функции, то тестирование каждого внутри os.walk

def find_files(dir_look, filters): 
    matches = [] 
    for root, dirnames, filenames in os.walk(dir_look): 
     for filt in filters: 
      for filename in fnmatch.filter(filenames, filt): 
       matches.append(os.path.join(root, filename)) 
    return matches 
+1

Теперь для каждого фильтра выполняется os.walk. это медленно. Может быть, лучше прочитать его один раз, а не просто запустить на нем фильтры? – Marcin

ответ

2

Этот Ответ будет посвящен алгоритмам и структурам данных, а не программированию на питоне.

  1. Если вы хотите протестировать множество шаблонов против строки, тогда вы должны выбрать лучшую структуру для представления. Вместо того, чтобы массив символов мы используем suffix-trees. (Для реализации питона см this question.

  2. Если некоторые из ваших фильтров имеют общие части (особенно, если они имеют один и тот же префикс), вы должны представить их как trie(s). Таким образом, таким образом, вы можете проверить одновременно с более чем одной моделью. Это решение создает накладные расходы на построение дерева (ов), но если вы используете одни и те же фильтры несколько раз, то это стоит.

+0

Спасибо Адаму, я раньше не видел суффиксов, но обязательно буду использовать их в будущем. Для этой проблемы мне нужны некоторые конкретные числа, но не числа между ними, то есть я хочу 60830007 и 60910259, но не 100 000 номеров между ними. Стоит ли строить дерево суффиксов? – jprockbelly

+1

Да, (я думаю), это так. Если вы создадите суффикс-дерево для имен файлов с длиной n в O (n) -O (nlogn), тогда сопоставление будет намного быстрее, потому что вам нужно найти ветку в дереве, содержащую фильтр, вместо этого через почти каждую букву. Даже лучшее время работы может быть достигнуто, если ваши фильтры содержат только цифры, потому что в этом случае вам нужно только построить (значительно меньшее) суффиксное дерево с числовыми частями имени файла. –