Python 程式設計/集合
從 2.3 版本開始,Python 提供了數學集合的實現。最初,此實現必須從標準模組set匯入,但在 Python 2.6 中,型別 set 和 frozenset 變成了內建型別。集合是物件的無序集合,與列表和元組等序列物件不同,在序列物件中,每個元素都有索引。集合不能包含重複的成員 - 給定物件在一個集合中出現 0 或 1 次。集合的所有成員都必須是可雜湊的,就像字典鍵一樣。整數、浮點數、元組和字串是可雜湊的;字典、列表和其他集合(除了 frozensets)不可雜湊。
Python 中的集合概覽
set1 = set() # A new empty set
set1.add("cat") # Add a single member
set1.update(["dog", "mouse"]) # Add several members, like list's extend
set1 |= set(["doe", "horse"]) # Add several members 2, like list's extend
if "cat" in set1: # Membership test
set1.remove("cat")
#set1.remove("elephant") - throws an error
set1.discard("elephant") # No error thrown
print(set1)
for item in set1: # Iteration AKA for each element
print(item)
print("Item count:", len(set1))# Length AKA size AKA item count
#1stitem = set1[0] # Error: no indexing for sets
isempty = len(set1) == 0 # Test for emptiness
set1 = {"cat", "dog"} # Initialize set using braces; since Python 2.7
#set1 = {} # No way; this is a dict
set1 = set(["cat", "dog"]) # Initialize set from a list
set2 = set(["dog", "mouse"])
set3 = set1 & set2 # Intersection
set4 = set1 | set2 # Union
set5 = set1 - set3 # Set difference
set6 = set1 ^ set2 # Symmetric difference
issubset = set1 <= set2 # Subset test
issuperset = set1 >= set2 # Superset test
set7 = set1.copy() # A shallow copy
set7.remove("cat")
print(set7.pop()) # Remove an arbitrary element
set8 = set1.copy()
set8.clear() # Clear AKA empty AKA erase
set9 = {x for x in range(10) if x % 2} # Set comprehension; since Python 2.7
print(set1, set2, set3, set4, set5, set6, set7, set8, set9, issubset, issuperset)
建立集合的一種方法是將任何順序物件傳遞給“set”建構函式。
>>> set([0, 1, 2, 3])
set([0, 1, 2, 3])
>>> set("obtuse")
set(['b', 'e', 'o', 's', 'u', 't'])
我們還可以使用“add”函式逐個向集合新增元素。
>>> s = set([12, 26, 54])
>>> s.add(32)
>>> s
set([32, 26, 12, 54])
請注意,由於集合不包含重複元素,因此如果我們再次將 s 的成員之一新增到 s 中,“add”函式將不起作用。相同的行為也發生在“update”函式中,該函式將一組元素新增到集合中。
>>> s.update([26, 12, 9, 14])
>>> s
set([32, 9, 12, 14, 54, 26])
請注意,您可以將任何型別的順序結構,甚至另一個集合,傳遞給 update 函式,無論用於初始化集合的結構是什麼。
set 函式還提供了一個複製建構函式。但是,請記住,複製建構函式將複製集合,但不會複製各個元素。
>>> s2 = s.copy()
>>> s2
set([32, 9, 12, 14, 54, 26])
我們可以使用與順序資料型別相同的“in”運算子檢查物件是否在集合中。
>>> 32 in s
True
>>> 6 in s
False
>>> 6 not in s
True
我們還可以測試整個集合的成員資格。給定兩個集合 和 ,我們檢查 是否是 的子集或超集。
>>> s.issubset(set([32, 8, 9, 12, 14, -4, 54, 26, 19]))
True
>>> s.issuperset(set([9, 12]))
True
請注意,“issubset”和“issuperset”也可以接受順序資料型別作為引數
>>> s.issuperset([32, 9])
True
請注意,<= 和 >= 運算子也分別表示 issubset 和 issuperset 函式。
>>> set([4, 5, 7]) <= set([4, 5, 7, 9])
True
>>> set([9, 12, 15]) >= set([9, 12])
True
與列表、元組和字串一樣,我們可以使用“len”函式查詢集合中的元素數量。
有三個函式可以從集合中移除單個元素,分別稱為 pop、remove 和 discard。第一個,pop,只是從集合中移除一個元素。請注意,對於它選擇移除哪個元素沒有定義的行為。
>>> s = set([1,2,3,4,5,6])
>>> s.pop()
1
>>> s
set([2,3,4,5,6])
我們還有“remove”函式來移除指定的元素。
>>> s.remove(3)
>>> s
set([2,4,5,6])
但是,移除集合中不存在的元素會導致錯誤。
>>> s.remove(9)
Traceback (most recent call last):
File "<stdin>", line 1, in ?
KeyError: 9
如果您希望避免此錯誤,請使用“discard”。它的功能與 remove 相同,但如果元素不在集合中,則只會不做任何事情
我們還有另一個用於從集合中移除元素的操作,clear,它只是從集合中移除所有元素。
>>> s.clear()
>>> s
set([])
我們還可以讓迴圈遍歷集合中的每個元素。但是,由於集合是無序的,因此迭代將遵循哪個順序是未定義的。
>>> s = set("blerg")
>>> for n in s:
... print(n, "", end="")
...
r b e l g
Python 允許我們執行所有標準的數學集合操作,使用集合的成員。請注意,每個集合操作都有幾種形式。其中一種形式,s1.function(s2) 將返回另一個集合,該集合是透過將“function”應用於 和 建立的。另一種形式,s1.function_update(s2),將更改 為透過 和 的“function”建立的集合。最後,一些函式有等效的特殊運算子。例如,s1 & s2 等效於 s1.intersection(s2)
任何同時存在於 和 中的元素都將出現在它們的交集中。
>>> s1 = set([4, 6, 9])
>>> s2 = set([1, 6, 8])
>>> s1.intersection(s2)
set([6])
>>> s1 & s2
set([6])
>>> s1.intersection_update(s2)
>>> s1
set([6])
兩個集合的並集是這兩個集合的合併。任何存在於 或 中的元素都將出現在它們的並集中。
>>> s1 = set([4, 6, 9])
>>> s2 = set([1, 6, 8])
>>> s1.union(s2)
set([1, 4, 6, 8, 9])
>>> s1 | s2
set([1, 4, 6, 8, 9])
請注意,並集的更新函式僅僅是“update” 上面提到的。
兩個集合的對稱差是屬於其中一個集合但不屬於兩個集合的元素的集合(在邏輯中也稱為異或)。
>>> s1 = set([4, 6, 9])
>>> s2 = set([1, 6, 8])
>>> s1.symmetric_difference(s2)
set([8, 1, 4, 9])
>>> s1 ^ s2
set([8, 1, 4, 9])
>>> s1.symmetric_difference_update(s2)
>>> s1
set([8, 1, 4, 9])
Python 還可以找到 和 的集合差,也就是屬於 但不屬於 的元素。
>>> s1 = set([4, 6, 9])
>>> s2 = set([1, 6, 8])
>>> s1.difference(s2)
set([9, 4])
>>> s1 - s2
set([9, 4])
>>> s1.difference_update(s2)
>>> s1
set([9, 4])
從 Python 2.6 開始,“union”、“intersection” 和“difference” 可以處理多個輸入。例如,使用“set.intersection()”。
>>> s1 = set([3, 6, 7, 9])
>>> s2 = set([6, 7, 9, 10])
>>> s3 = set([7, 9, 10, 11])
>>> set.intersection(s1, s2, s3)
set([9, 7])
凍結集(frozenset)基本上與集合相同,除了它是不可變的——一旦建立,其成員就不能更改。由於它們是不可變的,因此它們也是可雜湊的,這意味著凍結集可以用作其他集合中的成員以及字典的鍵。凍結集具有與普通集合相同的函式,除了所有更改內容的函式(update、remove、pop 等)都不可用。
>>> fs = frozenset([2, 3, 4])
>>> s1 = set([fs, 4, 5, 6])
>>> s1
set([4, frozenset([2, 3, 4]), 6, 5])
>>> fs.intersection(s1)
frozenset([4])
>>> fs.add(6)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'frozenset' object has no attribute 'add'
- 建立一個集合 {'cat', 1, 2, 3},並將其命名為 s。
- 建立一個集合 {'c', 'a', 't', '1', '2', '3'}。
- 建立一個凍結集 {'cat', 1, 2, 3},並將其命名為 fs。
- 建立一個包含凍結集 fs 的集合,它應該看起來像 {frozenset({'cat', 2, 3, 1})}。
- Python 教程,“資料結構”部分,“集合”小節 -- python.org
- Python 庫參考關於集合型別 -- python.org
- PEP 218 -- 新增內建集合物件型別,python.org,關於集合型別的簡潔概述