簡體   English   中英

在python中減去列表,優化速度

[英]subtraction of lists in python, optimising speed

為了找出python中兩個列表的替換,我使用:

names_of_files_not_dowloaded = [item for item in total_files if item not in names_of_files_downloaded]

有用。

列表的大小是:

文件總數56373個元素

下載的文件列表28464個元素

它持續34秒。 不知怎的,我有直覺說34秒太長了。 有沒有辦法更有效地進行減法?

謝謝

編輯:一個元素就像'AB12345'

列表沒有重復任何元素,它們已經設置好了

只需將files_downloaded設置為一個集合而不是列表。 列表需要對列表進行完整迭代,以便每次要進行檢查時進行成員資格檢查 但是,設置查找效率要高得多

只需使用:

downloaded_set = set(files_downloaded)
list_of_files_not_dowloaded = [item for item in total_files if item not in downloaded_set]

將列表放入集合中會產生初始成本,但之后的成員資格檢查會更快。


@ juanpa.arrivillaga也是另一個原因對性能的影響是在評論中提到in使用時設置在做字符串平等檢查,而哈希值進行比較,后者要便宜得多。

看來,如果我正在閱讀源代碼, CPython的列表會在檢查成員身份時使用直接相等檢查來進行比較 據推測,Sets使用哈希值,並且在Set創建時緩存它們。

如果您不關心元素的順序,並且您的列表不包含重復項,則可以使用:

diff = set(total_files) - set(files_downloaded)

如果您需要輸出作為列表:

diff = list(set(total_files) - set(files_downloaded))

set覆蓋__sub__()方法並將其用作設置差異,這正是您要查找的內容。

正如你的問題所說列表不包含dupes並且行為類似於集合,這應該可以獲得你想要的相對較好的性能。

total_files_set = set(total_files)
files_downloaded_set = set(files_downloaded)
files_not_dowloaded_set = total_files_set - files_downloaded_set 
list_of_files_not_dowloaded = list(files_not_dowloaded_set)

或者如果你想要一行:

list_of_files_not_dowloaded = list(set(total_files) - set(files_downloaded))

要了解有關使用集合的所有操作的更多信息,可以在此處進行檢查

編輯
我嘗試使用2個隨機列表計時兩種方法

  • 對於具有50,000個元素的子集和具有100,000個元素的超集
timeit.timeit('l = list(set(l1)-set(l2))', 
setup='import random; l1 = random.sample(range(1000000), 100000); l2 = random.sample(range(1000000), 50000)', 
number = 10)

輸出:

0.39393879500130424

timeit.timeit('l = [item for item in l1 if item not in l2]', \
setup='import random; l1 = random.sample(range(1000000), 10000); l2 = random.sample(range(1000000), 5000)', \
number = 1)

輸出:

98.58012624000003

如果您碰巧已經擁有兩個集合,而不必從列表轉換:

timeit.timeit('l = list(s2-s1)', 
setup='import random; s1 = set(random.sample(range(1000000), 100000)); s2 = set(random.sample(range(1000000), 50000))', 
number = 10)

輸出:

0.06160322100004123

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM