今天來講最後一個儲存資料的資料類型---集合(Set)。前幾天已經講了許多儲存資料的容器(List、Tuple、Dict),其實我已經學到不想再學了XD!我知道未來還有更多其他容器型別(Deque、Counter),所以還是先把基礎的先熟悉,如果我能活用這些的話,就已經夠我打天下了(笑。
集合跟昨天講到的字典一樣是無序的,而且集合的元素不能重複出現,不能透過數字進行索引。正因為它具有這些特性,所以通常用來進行一些資料中轉處理,如去除清單中重複的字元、或兩清單相同的元素(交集)等。
在建立集合時,Python集合有分為可變集合(set)和不可變集合(frozenset)。對可變集合(set),可以新增和刪除元素;對不可變集合(frozenset)則不允許這樣做。這樣的關係其實跟List和Tuple有點像呢!總之可變集合用大括弧能直接建立,而不可變集合要透過類型建置元frozenset()建立,如下:
empty_dict = {} #這其實是空字典喔!
empty_set = set() #這才是空集合(要用內建函式set())
set1 = {1, 2, 'abc', (10, 20)} #有初始資料的set
frozen_set = frozenset({1, 2, 'abc', (10, 20)}) #frozenset
set的容器物件,可以是字串、清單或元組,它就能將序列的資料元素作為集合元素。以下來看看它的特性吧:
>>> set1 = set('apple')
>>> set1
{'l', 'e', 'a', 'p'}
字串apple,由5個字元組成,其中p出現兩次,把它轉換成集合中,重複項只會保留一個,且順序不一樣。集合這種特性,也很適合讓我們去執行去重複的功能,如下:
list = [4,0,5,5,7,0,0,4,4]
set = set(list)
print(set)
{0, 4, 5, 7}
#可以再把它轉回串列
list = list(set)
由於集合本身是無序的,所以不能為集合建立索引或切片操作,只能循環檢查或使用in、not in來存取判斷集合元素:
>>> set1 = {'MON','TUE','WED','THU','FRI','SAT','SUN'}
>>> 'SAT' in set1
True
>>> 'Sean' in set1
False
>>> 'Sean' not in set1
True
再來是新增跟刪除資料,這裡跟之前用到的函式都很像,看看例子就好:
>>> set1 = {0,1,2,3,4,5}
>>> set1.add(6) #加入int6
>>> set1.add(3) #加入已有元素,無作用
>>> set1.remove(0) #移除0
>>> set1
{1, 2, 3, 4, 5, 6}
>>> set1.pop() #隨機移除、回傳
1
>>> set1.clear() #清空集合
Set最大的特色就是可以做「集合運算」,我先把集合運算相關的運算子整理起來(如下),最後我們再來看例子。
集合運算 | 集合運算子 | 對應集合物件的方法|運算|描述
------------- | -------------
聯集 | |
|union()|s1==s2|判斷集合是否相等
交集 | & |intersection()|s1<=s2|判斷s1是否是s2的子集
差集 | - |difference()|s1< s2|判斷s1是否是s2的真子集
對稱差集 | ^ |symmetric_difference()|s1>=s2|判斷s1是否是s2的超集合
聯集指定 | |=
|update()|s1>s2|判斷s1是否是s2的真超集合
交集指定 | &= |intersection_update()
差集指定 | -= |difference_update()
對稱差集指定 | ^= |symmetric_difference_update()
>>> s0 = {1,2,3,4}
>>> s1 = {3,4,5,6,7}
>>> s2 = {1,2,3}
>>> s2<=s0 #子集合
True
>>> s2<s0 #真子集合
True
>>> s0>s2,s0>s0 #超真集合
(True, False)
>>> s0|s1 #聯集
{1, 2, 3, 4, 5, 6, 7}
>>> s0&s1 #交集
{3, 4}
>>> s0-s1 #差集
{1, 2}
>>> s0^s1 #對稱差集
{1, 2, 5, 6, 7}
最後一點要注意的是,同一種集合運算,像是聯集,有運算子「|」和「union」方法可用,但運算子只能接受集合物件,而方法可以接受迭代者,如:
>>> s0 = {1,2,3,4}
>>> s0 | [3,4,5,6] #錯誤
>>> s0.union([3,4,5,6]) #方法可以接受
{1, 2, 3, 4, 5, 6}
>>> set('abc')&'bcd' #錯誤
>>> >>> set('abc').intersection('bcd')
{'c', 'b'}
不想再打第二次了受夠F5...