我有一个约3000个项目的列表。我们称之为listA
。 另一个包含1,000,000项的列表。我们称之为listB
。Python:如何获取一个列表中的项目数量
我想检查listB
中有多少项listA
。例如获得像436
这样的答案。
显而易见的方法是使用嵌套循环查找每个项目,但这很慢,特别是由于列表的大小。
什么是最快和/或Pythonic的方式来获得属于另一个列表的项目数量?
我有一个约3000个项目的列表。我们称之为listA
。 另一个包含1,000,000项的列表。我们称之为listB
。Python:如何获取一个列表中的项目数量
我想检查listB
中有多少项listA
。例如获得像436
这样的答案。
显而易见的方法是使用嵌套循环查找每个项目,但这很慢,特别是由于列表的大小。
什么是最快和/或Pythonic的方式来获得属于另一个列表的项目数量?
设置为list_b
。这将避免嵌套循环,并使包含检查O(1)
。整个过程将是O(M+N)
这应该是相当最佳:
set_b = set(list_b)
count = sum(1 for a in list_a if a in set_b)
# OR shorter, but maybe less intuitive
count = sum(a in set_b for a in list_a)
# where the bool expression is coerced to int {0; 1} for the summing
如果你不希望(或必须)在list_a
算重复的元素,你可以使用交集:
count = len(set(list_a) & set(list_b))
# OR
count = len(set(list_a).intersection(list_b)) # avoids one conversion
还应该注意的是,这些基于集合的操作仅适用于列表中的项目是可散列的(例如,不是列表本身)!
您可以通过跳过'list_b'的转换并使用方法形式:'set(list_a).intersection(list_b)'来简化第二个版本。 –
Thx,您是对的,添加了该选项。 – schwobaseggl
谢谢,那个工作就像一个魅力,它真的很快:) – Aventinus
您可以遍历的listA
的内容,并使用一台发电机,以产生价值更有效率:
def get_number_of_elements(s, a):
for i in s:
if i in a:
yield i
print(len(list(get_number_of_elements(listA, listB))))
如果'a'是一个列表,这并不解决嵌套循环的主要性能问题。 '我在''必须仍然遍历列表! 此外,生成器函数是相当错误的名称,因为它不返回元素的数量。 – schwobaseggl
@schwobaseggl生成器函数将生成's'中出现在'a'中的所有元素。通过将铸造生成器函数传递给'len'函数来计算重复次数。 – Ajax1234
我明白它在做什么;)但是a)它并不是解决OP想要解决的嵌套循环问题,b)'get_number_of_elements(...)'没有获得元素的数量,而是一个生成器说元素。 – schwobaseggl
另一种选择是使用set
并找到交集:
len(set(listA).intersection(listB))
大多数算法性能明智。在这种情况下,'listA'碰巧是最小的,但通常最小的迭代应该在'set()'中被调用来快速查找,而遍历则是更长的迭代。 – pstatix
执行列表有重复的值?订单(例如物品索引)是否重要? – pstatix