2017-09-25 63 views
-1

我有一個約3000個項目的列表。我們稱之爲listA。 另一個包含1,000,000項的列表。我們稱之爲listBPython:如何獲取一個列表中的項目數量

我想檢查listB中有多少項listA。例如獲得像436這樣的答案。

顯而易見的方法是使用嵌套循環查找每個項目,但這很慢,特別是由於列表的大小。

什麼是最快和/或Pythonic的方式來獲得屬於另一個列表的項目數量?

+0

執行列表有重複的值?訂單(例如物品索引)是否重要? – pstatix

回答

7

設置爲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 

還應該注意的是,這些基於集合的操作僅適用於列表中的項目是可散列的(例如,不是列表本身)!

+0

您可以通過跳過'list_b'的轉換並使用方法形式:'set(list_a).intersection(list_b)'來簡化第二個版本。 –

+0

Thx,您是對的,添加了該選項。 – schwobaseggl

+0

謝謝,那個工作就像一個魅力,它真的很快:) – Aventinus

0

您可以遍歷的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)))) 
+0

如果'a'是一個列表,這並不解決嵌套循環的主要性能問題。 '我在''必須仍然遍歷列表! 此外,生成器函數是相當錯誤的名稱,因爲它不返回元素的數量。 – schwobaseggl

+0

@schwobaseggl生成器函數將生成's'中出現在'a'中的所有元素。通過將鑄造生成器函數傳遞給'len'函數來計算重複次數。 – Ajax1234

+0

我明白它在做什麼;)但是a)它並不是解決OP想要解決的嵌套循環問題,b)'get_number_of_elements(...)'沒有獲得元素的數量,而是一個生成器說元素。 – schwobaseggl

2

另一種選擇是使用set並找到交集:

len(set(listA).intersection(listB)) 
+1

大多數算法性能明智。在這種情況下,'listA'碰巧是最小的,但通常最小的迭代應該在'set()'中被調用來快速查找,而遍歷則是更長的迭代。 – pstatix

相關問題