循环查找不在 python 列表中的项目的最有效方法
Most efficient way to loop finding items not in a list in python
我正在尝试提高脚本的效率,该脚本获取列表并计算有多少项目不在另一个 'master' 列表 (list_of_all_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()
接受任何可迭代对象,但它稍微快一些:
>>> 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
我正在尝试提高脚本的效率,该脚本获取列表并计算有多少项目不在另一个 'master' 列表 (list_of_all_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()
接受任何可迭代对象,但它稍微快一些:
>>> 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