Эффективный метод для исключения элементов из одного списка из другого списка в Python
У меня есть список из 8000 строк (стоп-слов) и список из 100 000 строк различной длины, которые могут включать миллионы отдельных слов. Я использую функцию для токенизации 100 000 строк и исключения не алфавитно-цифровых токенов и токенов из списка stop_words.
def tokenizer(text):
return [stemmer.stem(tok.lower()) for tok in nltk.word_tokenize(text)/
if tok.isalpha() and tok.lower() not in stop_words]
Я проверил этот код, используя 600 строк, и это занимает 60 секунд. Если я уберу условие для исключения стоп-слов, это займет 1 секунду на тех же 600 строках
def tokenizer(text):
return [stemmer.stem(tok.lower()) for tok in nltk.word_tokenize(text)/
if tok.isalpha()]
Я надеюсь, что есть более эффективный способ исключить элементы, найденные в одном списке из другого списка.
Я благодарен за любую помощь или предложения
Спасибо
3 ответа
- Делать
stop_words
набор, поскольку проверка членства в наборе - O(1), а проверка членства в списке - O(N). - Вызов
lower()
наtext
(один раз) вместоlower()
дважды за каждый токен.
stop_words = set(stop_words)
def tokenizer(text):
return [stemmer.stem(tok) for tok in nltk.word_tokenize(text.lower())
if tok.isalpha() and tok not in stop_words]
Поскольку доступ к локальным переменным происходит быстрее, чем поиск квалифицированных имен, вы также можете немного ускориться, если nltk.word_tokenize
а также stemmer.stem
местный:
stop_words = set(stop_words)
def tokenizer(text, stem = stemmer.stem, tokenize = nltk.word_tokenize):
return [stem(tok) for tok in tokenize(text.lower())
if tok.isalpha() and tok not in stop_words]
Значения по умолчанию для stem
а также tokenize
устанавливаются один раз во время tokenizer
функция определена. внутри tokenizer
, stem
а также tokenize
являются локальными переменными. Обычно этот вид микрооптимизации не важен, но так как вы звоните tokenizer
100K раз, это может помочь вам немного.
Делать stop_words
набор, так что вместо поиска O(1).
stop_words = set(('word1', 'word2', 'word3'))
Используйте наборы:
{x for x in one_list} - other_list
Однако он удаляет дубликаты и порядок, поэтому, если это важно, вам нужно что-то еще.