Я убежден Ответ Зака на правильном пути.Из любопытства я реализовал другую версию (включающую комментарии Зака об использовании dict вместо bisect
) и свел ее в решение, соответствующее вашему примеру.
#!/usr/bin/env python
import re
from trieMatch import PrefixMatch # https://gist.github.com/736416
pm = PrefixMatch(['YELLOW', 'GREEN', 'RED', ]) # huge list of 10 000 members
# if list is static, it might be worth picking "pm" to avoid rebuilding each time
f = open("huge_file.txt", "r") ## file with > 100 000 lines
lines = f.readlines()
f.close()
regexp = re.compile(r'^.*?fruit=([A-Z]+)')
filtered = (line for line in lines if pm.match(regexp.match(line).group(1)))
Для краткости, реализация PrefixMatch
is опубликовано здесь .
Если ваш список necessary
префиксов статичен или изменяется нечасто, вы можете ускорить последующие запуски, выбрав и повторно использовав объект PickleMatch
вместо восстановленияэто каждый раз.
обновление (по отсортированным результатам)
Согласно changelog для Python 2.4 :
ключ должен бытьоднопараметрическая функция, которая принимает элемент списка и возвращает ключ сравнения для элемента.Затем список сортируется с помощью клавиш сравнения.
также, в исходный код, строка 1792 :
/* Special wrapper to support stable sorting using the decorate-sort-undecorate
pattern. Holds a key which is used for comparisons and the original record
which is returned during the undecorate phase. By exposing only the key
.... */
Это означает, что ваш шаблон регулярного выраженияоценивается только один раз для каждой записи (не один раз для каждого сравнения), поэтому это не должно быть слишком дорого:
sorted_generator = sorted(filtered, key=regexp.match(line).group(1))