5.2. 集合
接下要來介紹的Python資料結構是集合,集合和字典有一些相同的地方,例如:集合中的元素及字典中的鍵是唯一的;兩者不同的地方則是字典的鍵還有其對的值,而集合僅有元素。
建立集合
>>> s = set()
>>> s
set()
>>> type(s)
<class 'set'>
>>> s = {1, 2, 3, 4, 5}
>>> s
{1, 2, 3, 4, 5}
>>> type(s)
<class 'set'>
雖然集合和字典都是使用「{ }」符號,但是Python的直譯器優先把「{ }」解釋成字典,所以字典優先使用此符號。如果資料結構的建立方式不同,Python直譯器就會識別出該資料結構是字典或集合。
>>> s = {}
>>> s
{}
>>> type(s)
<class 'dict'>
>>> s = {1}
>>> s
{1}
>>> type(s)
<class 'set'>
使用 len() 取得集合元素數量
使用 len() 可以取得集合中元素的數量。
>>> s = {1, 2, 3, 4, 5}
>>> len(s)
5
使用 in 判斷元素是否在集合中
若需要知道某個元素是否在集合中時,可以使用 in 關鍵值來判斷。
>>> s = {1, 2, 3, 4, 5}
>>> 1 in s
True
>>> 1.0 in s
True
>>> '1' in s
False
使用 add() 加入資料
使用 add() 將元素加入到集合中。
>>> s = set()
>>> s.add(1)
>>> s
{1}
>>> s.add(2)
>>> s
{1, 2}
>>> s.add(3)
>>> s
{1, 2, 3}
使用 remove() 移除資料
使用 remove() 將要移除的元素從集合移出。
>>> s = {1, 2, 3, 4, 5}
>>> s.remove(1)
>>> s
{2, 3, 4, 5}
>>> s.remove(2)
>>> s
{3, 4, 5}
使用 clear() 可以刪除集合中所有的資料,或是使用 = 指派運算子及指派空集合 set() 來達成。
>>> s = {1, 2, 3, 4, 5}
>>> s.clear()
>>> s
set()
>>> s = {1, 2, 3, 4, 5}
>>> s = set()
>>> s
set()
集合運算
- 聯集:| , union(),兩個集合中所有的元素。
- 交集:& , intersection() ,兩個集合中共有的元素。
- 差集:- , difference(),屬於第一個集合,但不屬於第二個集合的元素。
- 互斥或:^ , symmetric_difference(),只屬於其中一個集合的元素。
>>> a = {1, 2, 3}
>>> b = {3, 4, 5}
>>> a
{1, 2, 3,}
>>> b
{3, 4, 5}
# 聯集
>>> c = a | b
>>> c
{1, 2, 3, 4, 5}
>>> c = a.union(b)
>>> c
{1, 2, 3, 4, 5}
# 交集
>>> c = a & n
>>> c
{3}
>>> c = a.intersection(b)
>>> c
{3}
# 差集
>>> c = a - b
>>> c
{1, 2}
>>> c = a - (a & b)
>>> c
{1, 2}
>>> c = a.difference(b)
>>> c
{1, 2}
# 互斥或
>>> c = a ^ b
>>> c
{1, 2, 4, 5}
>>> c = (a | b) - (a & b)
>>> c
{1, 2, 4, 5}
>>> c = a.symmetric_difference(b)
>>> c
{1, 2, 4, 5}
牛刀小試
- b050: 第一題:集合運算 [參考答案] ★★
- 使用 for 迴圈、while 迴圈、if結構、if-else結構、集合
- 程式設計步驟:
# 步驟1: 定義變數, case_index
case_index = 1
# 步驟2: 使用while迴圈
while True:
# 步驟3: 處理資料輸入
s = input("")
s = s.strip(" \t\r\n")
# 步驟4: 資料類型轉換
n = int(s)
# 步驟5: 使用if結構判斷是否要結束while迴圈
if n == 0:
break
print("Test Case {0}:".format(case_index))
# 步驟6: 使用for迴圈讀取集合資料
set_list = []
for i in range(0, n):
s = input("")
s = s.strip(" \t\r\n")
set_list.append(s)
num_set = len(set_list)
# 步驟7: 顯示集合資料
for i in range(0, num_set):
name = chr(i + 65)
a = set_list[i]
a = ''.join(sorted(a))
print(name + ': {' + a + '}')
# 步驟8: 使用集合的聯集運算
# A | B
for i in range(0, num_set):
name_a = chr(i + 65)
a = set(set_list[i])
for j in range(i+1, num_set):
name_b = chr(j + 65)
b = set(set_list[j])
ab = a | b
ab = ''.join(sorted(ab))
print(name_a + '+' + name_b + ': {' + ab + '}')
# 步驟9: 使用集合的交集運算
# A & B
for i in range(0, num_set):
name_a = chr(i + 65)
a = set(set_list[i])
for j in range(i+1, num_set):
name_b = chr(j + 65)
b = set(set_list[j])
ab = a & b
ab = ''.join(sorted(ab))
print(name_a + '*' + name_b + ': {' + ab + '}')
# 步驟10: 使用集合的差集運算
# A - B
for i in range(0, num_set):
name_a = chr(i + 65)
a = set(set_list[i])
for j in range(0, num_set):
if i != j:
name_b = chr(j + 65)
b = set(set_list[j])
ab = a - b
ab = ''.join(sorted(ab))
print(name_a + '-' + name_b + ': {' + ab + '}')
# 步驟11: 判斷集合是否包含另一個集合
# A > B
for i in range(0, num_set):
name_a = chr(i + 65)
a = set(set_list[i])
for j in range(0, num_set):
if i != j:
name_b = chr(j + 65)
b = set(set_list[j])
if a >= b:
print(name_a + ' contains ' + name_b)
else:
print(name_a + ' does not contain ' + name_b)
case_index +=1
躍躍欲試
- 集合:
- d478: 共同的數 - 簡易版 [參考答案]
參考資料
- Built-in Types, Set Types
- Python編程入門第3版(簡), 第七章, Toby Donaldson著, 人民郵電出版社
- 精通Python, 第三章, Bill Lubanovic著, 賴屹民譯, 歐萊禮