2013-01-12 59 views
3

我有一個包含8000個字符串(stop_words)的列表以及一串由數百萬個單詞組成的各種長度的100,000個字符串。我正在使用該函數標記100,000字符串,並從列表stop_words中排除非字母數字標記和標記。從Python中的另一個列表中排除一個列表中的項目的有效方法

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秒。如果我刪除的條件,排除禁用詞它將採用相同的600串

def tokenizer(text): 

     return [stemmer.stem(tok.lower()) for tok in nltk.word_tokenize(text)/ 
     if tok.isalpha()] 

我希望有排除從其他列表中的一個列表中找到的項目進行更有效的方式1秒。

我很感激任何幫助或建議

感謝

+0

嘗試'設置'排除類似的項目。 'set(list1).difference(list2)'[see](http://docs.python.org/2/library/sets.html) – Developer

回答

3
  • stop_words一組,由於checking membership in a set是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_tokenizestemmer.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] 

stemtokenize的默認值設置爲一次當時tokenizer功能是定義爲。在tokenizer內,stemtokenize是局部變量。通常這種微型優化並不重要,但由於您要求100K次,所以它可能會對您有所幫助。

+0

謝謝,這在我的測試中再次獲得了第二名。 – bradj

5

stop_words一組,這樣查找是O(1)替代。

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

謝謝 - 這是一個更快的方法 – bradj

0

使用裝置:

{x for x in one_list} - other_list 

但是它消除重複和排序,所以如果它的事項,你需要別的東西。

+0

謝謝,雖然在這種情況下,我確實需要保持謙虛態度 – bradj

相關問題