Python Set 集合

Python Set(Python Set)

這篇 Python Set 教學將帶你認識集合:一個無順序、元素不重複的容器。Set 有兩個殺手級用途:一行去除 List 的重複元素,以及用數學的交集、聯集、差集比對兩批資料。

建立 Set 與去除重複

用大括號 {} 建立(注意:裡面是單一元素,不是 key: value)。最常見的用法是 set() 把 List 去重複:

tags = {"python", "sql", "python"}   # 重複的自動消失
print(tags)

# 經典用法:List 去除重複
emails = ["a@test.com", "b@test.com", "a@test.com", "c@test.com"]
unique = list(set(emails))
print(len(emails), "->", len(unique))

執行輸出:

{'sql', 'python'}
4 -> 3

注意 Set 是無順序的,印出來的順序不固定;去重後若需要保留原順序,可用 list(dict.fromkeys(emails))

新增與移除元素

方法說明
add(x)加入元素(已存在則無效果)
remove(x)移除元素(不存在會報 KeyError)
discard(x)移除元素(不存在也不報錯)
x in s檢查元素是否存在(速度極快)
s = {1, 2, 3}
s.add(4)
s.add(2)        # 已存在,沒有變化
s.discard(99)   # 不存在也不報錯
print(s)
print(3 in s)

執行輸出:

{1, 2, 3, 4}
True

交集、聯集、差集

比對兩批資料時超好用:

運算寫法意義
交集a & b兩邊都有的
聯集a | b出現在任一邊的
差集a - b在 a 但不在 b 的
對稱差集a ^ b只出現在其中一邊的

實例:找出兩個班都有選的課、以及只有 A 班選的課:

class_a = {"國文", "英文", "數學", "物理"}
class_b = {"英文", "數學", "化學"}

print(class_a & class_b)   # 交集:兩班都有
print(class_a | class_b)   # 聯集:所有出現過的課
print(class_a - class_b)   # 差集:只有 A 班有

執行輸出:

{'數學', '英文'}
{'物理', '英文', '化學', '數學', '國文'}
{'國文', '物理'}

(Set 無順序,你的輸出順序可能不同。)

常見錯誤

1. 用 {} 建立空集合

s = {} 建立的是空字典不是空集合!空集合一定要寫 s = set()

2. TypeError: unhashable type: ‘list’

把 List 放進 Set({[1, 2]})。和字典的 key 一樣,Set 的元素必須是不可變型別,序列請改用 Tuple。

3. 對 Set 使用索引

s[0] 會報 TypeError,因為 Set 無順序、沒有索引。需要索引就先 list(s) 轉成 List。

總結

Set 的三個關鍵:元素不重複(set() 一行去重)、無順序(不能索引)、支援交聯差集運算(&|-)。記住空集合是 set() 不是 {}。到這裡四大容器(List、Tuple、Dictionary、Set)都認識了,下一篇學 Python 最優雅的語法之一:List Comprehension。

延伸閱讀