在 Python 程式設計中,集合 (set) 是一種獨特的資料結構,用於儲存無序且不重複的元素。本文將詳細介紹 Python 集合的定義、建立方式、特性、基本操作、集合運算、常用方法,以及實際應用。
什麼是集合 (set)?
集合是由一群不重複的元素組成的無序資料結構。集合具有以下特點:
- 無序性 (Unordered): 集合中的元素沒有固定的順序 (不像串列和元組)。
- 不重複性 (Unique Elements): 集合中不能包含重複的元素。如果嘗試新增重複的元素,集合會自動忽略。
- 可變性 (Mutable): 集合的內容可以修改 (新增、刪除元素)。 (但請注意, 集合內的元素必須是不可變的)
- 可雜湊性 (Hashable Elements):** 集合中的元素必須是可雜湊的 (hashable),這意味著它們必須是不可變的資料型別 (例如整數、浮點數、字串、元組),不能是可變的資料型別 (例如串列、字典、集合)。
在 Python 中,集合屬於 set
型別。
重要觀念: Python 另有一個 frozenset 型別, 它是不可變的集合, 建立後就不能修改。frozenset 可以當作另一個集合的元素, 或是 dictionary 的 key。
建立集合
有幾種方式可以建立集合:
- 使用大括號
{}
(最常見): 將元素用逗號分隔, 並放在大括號中。 *注意: 空的{}
會建立一個空的字典, 而不是空的集合* - 使用
set()
函數:- 不傳入參數, 建立空集合。
- 傳入一個可迭代物件 (例如字串、串列、元組)。
# 使用大括號 {}
my_set = {1, 2, 3, 4, 5}
fruits = {'apple', 'banana', 'orange', 'apple'} # 重複的 'apple' 會被自動去除
print(fruits) # 輸出: {'orange', 'banana', 'apple'} (順序不一定)
# 使用 set() 函數
empty_set = set() # 建立空集合
string = "Hello"
char_set = set(string) # 輸出: {'H', 'e', 'l', 'o'} (重複的 'l' 被去除,順序不一定)
list_data = [10, 20, 30, 20, 10]
set_from_list = set(list_data) # 輸出: {10, 20, 30}
print(type(my_set)) # 輸出: <class 'set'>
集合的基本操作
- 新增元素:
add(item)
: 新增單一元素。update(iterable)
: 新增多個元素。
- 刪除元素:
remove(item)
: 刪除指定元素, 如果元素不存在, 會引發 KeyError。discard(item)
: 刪除指定元素, 如果元素不存在, 則不做任何事。pop()
: 隨機移除並返回一個元素 (因為集合是無序的)。如果集合為空, 會引發 KeyError。clear()
: 清空集合。
- 檢查元素是否存在:
in
,not in
- 計算長度:
len(set)
my_set = {1, 2, 3}
# 新增元素
my_set.add(4) # {1, 2, 3, 4}
my_set.update([4, 5, 6]) # {1, 2, 3, 4, 5, 6} (重複的 4 會被忽略)
print(my_set)
# 刪除元素
my_set.remove(3) # {1, 2, 4, 5, 6}
# my_set.remove(7) # 引發 KeyError: 7
my_set.discard(7) # 沒事發生, 因為7本來就不在
popped_element = my_set.pop() # 隨機移除一個元素
print(popped_element) # 可能是 1, 2, 4, 5, 6 的其中一個
print(my_set)
print(2 in my_set) # True or False (根據pop結果而定)
my_set.clear()
print(len(my_set)) # 輸出: 0
集合運算 (Set Operations)
Python 集合支援各種集合運算:
- 聯集 (
|
或union()
): 包含兩個集合中所有不重複的元素。 - 交集 (
&
或intersection()
): 包含同時存在於兩個集合中的元素。 - 差集 (
-
或difference()
): 包含存在於第一個集合但不存在於第二個集合的元素。 - 對稱差集 (
^
或symmetric_difference()
): 包含只存在於其中一個集合的元素 (不同時存在於兩個集合)。 - 子集合 (
<=
), 真子集合(<
), 超集合(>=
), 真超集合(>
)
set1 = {1, 2, 3, 4, 5}
set2 = {4, 5, 6, 7, 8}
# 聯集
print(set1 | set2) # 輸出: {1, 2, 3, 4, 5, 6, 7, 8}
print(set1.union(set2)) # 輸出: {1, 2, 3, 4, 5, 6, 7, 8}
# 交集
print(set1 & set2) # 輸出: {4, 5}
print(set1.intersection(set2)) # 輸出: {4, 5}
# 差集
print(set1 - set2) # 輸出: {1, 2, 3} (set1 中有,但 set2 中沒有)
print(set2 - set1) # 輸出: {8, 6, 7} (set2 中有,但 set1 中沒有)
print(set1.difference(set2)) # 輸出: {1, 2, 3}
# 對稱差集
print(set1 ^ set2) # 輸出: {1, 2, 3, 6, 7, 8}
print(set1.symmetric_difference(set2)) # 輸出: {1, 2, 3, 6, 7, 8}
#子集合
set3 = {1,2}
print(set3 <= set1) # True
print(set3 < set1) # True
常用方法和進階操作
除了前面提到的基本操作和集合運算外,Python 集合還提供了一些其他常用的方法:
isdisjoint(other_set)
: 判斷兩個集合是否沒有交集 (沒有共同元素),如果沒有交集返回True
,否則返回False
。copy()
: 返回集合的淺拷貝 (shallow copy)。
set1 = {1, 2, 3}
set2 = {4, 5, 6}
set3 = {3, 4}
print(set1.isdisjoint(set2)) # 輸出: True (沒有共同元素)
print(set1.isdisjoint(set3)) # 輸出: False (有共同元素 3)
set4 = set1.copy() # 建立 set1 的淺拷貝
set4.add(4)
print(set1) # 輸出: {1, 2, 3} (set1 不受影響)
print(set4) # 輸出: {1, 2, 3, 4}
集合的迭代
您可以使用 for
迴圈來迭代集合中的元素,但請注意,由於集合是無序的,迭代的順序是不確定的:
my_set = {'apple', 'banana', 'orange'}
for fruit in my_set:
print(fruit) # 輸出順序不確定,可能是 'orange', 'banana', 'apple'
frozenset (凍結集合)
Python 提供了一種不可變的集合型別 frozenset
。 frozenset
一旦建立後,就不能再新增、刪除或修改元素。 這使得 frozenset
可以作為字典的鍵 (key) 或另一個集合的元素,而一般的 set
則不行。
# 建立 frozenset
frozen_set = frozenset([1, 2, 3, 2]) # 重複的 2 會被自動去除
print(frozen_set) # 輸出: frozenset({1, 2, 3})
# frozenset 可以作為字典的鍵
my_dict = {frozen_set: 'This is a key'}
print(my_dict[frozen_set]) #輸出: This is a key
# frozenset 可以作為另一個集合的元素
another_set = {frozen_set, 4, 5}
print(another_set) # 輸出: {frozenset({1, 2, 3}), 4, 5}
# 以下操作會引發錯誤,因為 frozenset 是不可變的
# frozen_set.add(4) # AttributeError: 'frozenset' object has no attribute 'add'
# frozen_set.remove(1) # AttributeError: 'frozenset' object has no attribute 'remove'
集合的應用
- 去除重複元素: 將串列或其他可迭代物件轉換為集合,可以快速去除重複元素。
- 成員資格測試: 快速判斷一個元素是否存在於集合中 (
in
和not in
運算)。 - 集合運算: 進行交集、聯集、差集等操作,例如,找出兩個使用者共有的興趣、找出只在其中一個使用者中出現的興趣等。
- 資料過濾: 從資料中篩選出符合特定條件的唯一元素。
總結
Python 的集合 (set) 是一種無序、不重複元素的資料結構,提供了高效的成員資格測試和集合運算。 了解集合的特性和用法,可以幫助您在處理需要唯一性和集合運算的場景時,寫出更簡潔、更有效率的程式碼。 了解了可變的set與不可變的frozenset的差異與應用,可以讓程式設計更為彈性。