Python 集合 (set) 型別詳解:建立、操作、方法與應用

Python 集合 (set) 型別詳解:建立、操作、方法與應用

在 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 提供了一種不可變的集合型別 frozensetfrozenset 一旦建立後,就不能再新增、刪除或修改元素。 這使得 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'

集合的應用

  • 去除重複元素: 將串列或其他可迭代物件轉換為集合,可以快速去除重複元素。
  • 成員資格測試: 快速判斷一個元素是否存在於集合中 (innot in 運算)。
  • 集合運算: 進行交集、聯集、差集等操作,例如,找出兩個使用者共有的興趣、找出只在其中一個使用者中出現的興趣等。
  • 資料過濾: 從資料中篩選出符合特定條件的唯一元素。

總結

Python 的集合 (set) 是一種無序、不重複元素的資料結構,提供了高效的成員資格測試和集合運算。 了解集合的特性和用法,可以幫助您在處理需要唯一性和集合運算的場景時,寫出更簡潔、更有效率的程式碼。 了解了可變的set與不可變的frozenset的差異與應用,可以讓程式設計更為彈性。

張貼留言

較新的 較舊