【问题标题】:Efficient method to exclude items in one list from another list in Python从 Python 中的另一个列表中排除一个列表中的项目的有效方法
【发布时间】:2012-12-26 22:43:39
【问题描述】:

我有一个包含 8000 个字符串 (stop_words) 的列表和一个包含 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 秒。如果我删除排除停用词的条件,则在相同的 600 个字符串上需要 1 秒

    def tokenizer(text):

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

我希望有一种更有效的方法可以从另一个列表中排除在一个列表中找到的项目。

感谢任何帮助或建议

谢谢

【问题讨论】:

  • 尝试set 排除类似项目。 set(list1).difference(list2)see

标签: python string list tokenize stop-words


【解决方案1】:

stop_words 设为一个集合,以便查找改为 O(1)。

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

【讨论】:

  • 谢谢-这要快很多
【解决方案2】:

使用集:

{x for x in one_list} - other_list

但是它会删除重复项和排序,所以如果它很重要,你需要其他东西。

【讨论】:

  • 谢谢,虽然在这种情况下我确实需要保留副本
【解决方案3】:
  • stop_words 设为一个集合,因为checking membership in a set 是O(1), 同时检查列表中的成员资格是 O(N)。
  • text(一次)上调用lower(),而不是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 函数定义时设置一次tokenizerstemtokenize 内部是局部变量。通常这种微优化并不重要,但既然你打电话给tokenizer 100K次,可能对你有点帮助。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-05-25
    • 2011-02-14
    • 1970-01-01
    相关资源
    最近更新 更多