Python 中對兩個列表進行集合運算(差集、並集、交集)有多種寫法,各有效能與可讀性差異。本文整理三種主流實現並給出效能建議。
a = [1, 2, 3]
b = [2, 3]
# 期望差集 a - b = [1]
ret = []
for i in a:
if i not in b:
ret.append(i)
# ret = [1]
ret = [i for i in a if i not in b]
# ret = [1]
ret = list(set(a) ^ set(b)) # 對稱差集:[1](元素在 a 或 b 但不同時在兩者)
ret = list(set(a) - set(b)) # 差集 a - b:[1]
ret = list(set(b) - set(a)) # 差集 b - a:[]
ret = list(set(a) | set(b)) # 並集:[1, 2, 3]
ret = list(set(a) & set(b)) # 交集:[2, 3]
import timeit
a = list(range(100000))
b = list(range(50000, 150000))
t1 = timeit.timeit('[i for i in a if i not in b]', globals=globals(), number=1)
t2 = timeit.timeit('list(set(a) - set(b))', globals=globals(), number=1)
print(f'列表推導式: {t1:.3f}s') # ~0.8s
print(f'集合運算: {t2:.3f}s') # ~0.01s
集合運算因哈希查找 O(1),大數據量下快 50-100 倍。
lists = [[1,2,3], [2,3,4], [3,4,5]]
# 所有列表的交集
intersection = set(lists[0]).intersection(*lists[1:]) # {3}
# 所有列表的並集
union = set().union(*lists) # {1,2,3,4,5}
# 第一個列表減去其餘所有
diff = set(lists[0]).difference(*lists[1:]) # {1}
掌握三種寫法並根據場景選擇,能寫出既 Pythonic 又高效的代碼。