在python中循环查找不在列表中的项的最有效方法

在python中循环查找不在列表中的项的最有效方法,python,list,for-loop,Python,List,For Loop,我试图提高脚本的效率,该脚本获取列表并计算有多少项不在另一个“主”列表中(list\u of\u all\u items) 感觉可能有一种更有效的方法可以做到这一点,也许可以通过某种方式组合查询 purple_count, brown_count, blue_count = 0, 0, 0 for item in list_of_purple_items: if item not in list_of_all_items: purple_count += 1 for

我试图提高脚本的效率,该脚本获取列表并计算有多少项不在另一个“主”列表中(
list\u of\u all\u items

感觉可能有一种更有效的方法可以做到这一点,也许可以通过某种方式组合查询

purple_count, brown_count, blue_count = 0, 0, 0

for item in list_of_purple_items:
    if item not in list_of_all_items:
        purple_count += 1

for item in list_of_brown_items:
    if item not in list_of_all_items:
        brown_list += 1

for item in list_of_blue_items:
    if item not in list_of_all_items:
        blue_count += 1
编辑:

谢谢你的帮助。我运行了一个快速测试,以了解使用大型测试用例的最佳方式:

    my original: 30.21s
           sets: 00.02s
         filter: 30.01s
  sum generator: 31.08s
令人惊讶的是,它使用集合的效率提高了很多


再次感谢大家。

您可以将
sum
与生成器表达式一起使用,并将您的列表转换为
set
,以更有效地检查成员资格:

main_set=set(list_of_all_items)
sum(1 for i in set(list_of_purple_items) if i not in main_set)
使用集合,这样就不必继续循环:

set_of_all_items = set(list_of_all_items)
purple_count = len(set(list_of_purple_items).difference(list_of_all_items))
brown_count = len(set(list_of_brown_items).difference(list_of_all_items))
blue_count = len(set(list_of_blue_items).difference(list_of_all_items))
这是更有效的,因为集合交叉点只需要在两个集合中的一个集合上循环;然后,每个项目可以在固定时间内与另一组项目进行测试。循环是在C代码中完成的(当创建
set
对象和计算差异时)

实际上并不需要为所有项目使用集合,因为
set.difference()
需要任何iterable,但速度稍快一些:

>>> import timeit
>>> import random
>>> all = range(10000)
>>> random.shuffle(all)
>>> all[:-1000] = []
>>> some = [random.randrange(10000) for _ in range(1000)]
>>> timeit.timeit('len(set(some).difference(all))', 'from __main__ import some, all', number=10000)
0.9517788887023926
>>> timeit.timeit('len(set(some).difference(all))', 'from __main__ import some, all; all = set(all)', number=10000)
0.90407395362854

没有意识到
set
s在C级工作,现在就更有理由使用它们!