Эффективный метод для исключения элементов из одного списка из другого списка в 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 являются локальными переменными. Обычно этот вид микрооптимизации не важен, но так как вы звоните tokenizer100K раз, это может помочь вам немного.

Делать stop_words набор, так что вместо поиска O(1).

stop_words = set(('word1', 'word2', 'word3'))

Используйте наборы:

{x for x in one_list} - other_list

Однако он удаляет дубликаты и порядок, поэтому, если это важно, вам нужно что-то еще.

Другие вопросы по тегам