Python:列表理解-更快的替代方案?

Python:列表理解-更快的替代方案?,python,list,list-comprehension,Python,List,List Comprehension,我有两份清单: 单词列表所有单词(~100.000个元素) 停止字列表停止字(~2000个元素) 我想从列表allwords生成一个新列表selectedwords,其中包含所有不在stopwords中的单词 我通过下面的列表实现了这一点 selectedwords = [word.lower() for word in allwords if word.lower() not in stopwords] 问题:有没有更聪明的方法来加速计算(使用python)。我是python新手,非常感谢

我有两份清单:

  • 单词列表
    所有单词
    (~100.000个元素)
  • 停止字列表
    停止字
    (~2000个元素)
  • 我想从列表
    allwords
    生成一个新列表
    selectedwords
    ,其中包含所有不在
    stopwords
    中的单词

    我通过下面的列表实现了这一点

    selectedwords = [word.lower() for word in allwords  if word.lower() not in stopwords]
    
    问题:有没有更聪明的方法来加速计算(使用python)。我是python新手,非常感谢您的建议


    谢谢

    Make
    stopwords
    a
    set
    ,则
    not in
    检查很快

    编辑:一些基准测试将其与@deceze的方法进行比较(我删除了
    .lower()
    ,并准备了停止词集(不管怎样,它很小),以便关注这两种方法的实际差异)

    输出(三轮,左侧时间为列表理解,右侧时间为设置差):

    因此,在这项测试中,列表理解始终明显快于集合差异

    为了进行比较,使用“停止词列表”进行测试:


    使
    stopwords
    a
    set
    ,则
    不在
    检查很快

    编辑:一些基准测试将其与@deceze的方法进行比较(我删除了
    .lower()
    ,并准备了停止词集(不管怎样,它很小),以便关注这两种方法的实际差异)

    输出(三轮,左侧时间为列表理解,右侧时间为设置差):

    因此,在这项测试中,列表理解始终明显快于集合差异

    为了进行比较,使用“停止词列表”进行测试:


    假设这些列表中没有重复项和/或您仍然希望消除列表中的重复项,并且您不关心顺序,创建两个集合并获得差异:

    0.5209118997490783 0.9618692664857642
    0.5104636869544419 0.9020013947776662
    0.48269282831284466 0.8888132040554915
    
    selectedwords = set(map(str.lower, allwords)) - set(stopwords)
    

    假设这些列表中没有重复项和/或您仍然希望消除列表中的重复项,并且您不关心顺序,创建两个集合并获得差异:

    0.5209118997490783 0.9618692664857642
    0.5104636869544419 0.9020013947776662
    0.48269282831284466 0.8888132040554915
    
    selectedwords = set(map(str.lower, allwords)) - set(stopwords)
    

    将两个列表设置为一个
    集合
    ,并获得差异…@deceze,这将丢失顺序和重复项,从而无法实现相同的效果。我不希望出现重复项,OP也没有指定顺序相关,但是,好的,这可能是一个原因。谢谢,Stefan。这大大加快了这个过程,并且仍然在所有单词的列表中保留了重复的单词(我需要这些单词,但我没有具体说明)。为什么使用set要快得多?@FredMaster的基本思想是
    set
    创建索引,这就像把一个单词列表变成一个有序的纸质词典。将两个列表都设置成一个
    集合
    ,然后得到不同的…@deceze,这将丢失顺序和重复项,从而无法实现相同的效果。我不希望出现重复项,OP也没有指定顺序相关,但是,好的,这可能是个原因谢谢Stefan。这大大加快了这个过程,并且仍然在所有单词的列表中保留了重复的单词(我需要这些单词,但我没有具体说明)。为什么使用set会快得多?@FredMaster基本思想是
    set
    创建一个索引,这就像将一个单词列表转换成一个有序的纸质词典。调用
    word.lower()
    两次没有帮助。谢谢。我来看看。两次调用
    word.lower()
    都没有帮助。谢谢。我会看看这个。我很确定计算集合差异的算法仍然只是在第一个列表上迭代,因此首先将
    allwords
    转换为
    set
    并不能真正加快速度。可以使用
    set(map(str.lower,allwords))
    @chepner,这取决于我认为的实现。在C中实现时,使用本机集差异方法可能比Python循环快得多。
    selectedwords=list(sorted(set(…)-set(…))
    准确地说(
    sorted
    当然是可选的)。首先构建集是个问题;如果你仅仅为了计算这个差异而构建集合,那么就没有净收益。我很确定计算集合差异的算法仍然只是在第一个列表上迭代,因此将
    allwords
    首先转换为
    set
    并不能真正加快速度。可以使用
    set(map(str.lower,allwords))
    @chepner,我想这取决于实现。在C中实现时,使用本机集差异方法可能比Python循环快得多。
    selectedwords=list(sorted(set(…)-set(…))
    准确地说(
    sorted
    当然是可选的)。首先构建集是个问题;如果您构建集合只是为了计算此差异,则没有净收益。