第027講:集合:在我的世界裡,你就是唯一
目錄
4. 請問 set1 = {[1, 2]} 和 set1 = set([1, 2]) 執行的結果一樣嗎?
5. 開啟你的IDLE,輸入set1 = {1, 1.0},你發現了什麼?
0. 自學擴充套件:自己花點時間看下這個表格(http://bbs.fishc.com/thread-45276-1-1.html),今後會用上的^_^
測試題
0. 請問集合的唯一作用是什麼呢?
答:集合幾乎所有的作用就是確保裡邊包含的元素的唯一性,就像世界上沒有兩片完全相同的樹葉一樣,集合內不可能存在兩個相同的元素!
1. 如果你希望建立的集合是不變的,應該怎麼做?
答:frozenset()
2. 請問如何確定一個集合裡邊有多少個元素?
答:沒錯,len()函式正好可以滿足你此刻的需求^_^
3. 請目測以下程式碼會列印什麼內容?
>>> num_set = set([1, 2, 3, 4, 5])
>>> num_set[0]
答:會報錯,因為集合是無序的。
4. 請問 set1 = {[1, 2]} 和 set1 = set([1, 2]) 執行的結果一樣嗎?
答:不一樣,set1 = set([1, 2]) 會生成一個集合{1, 2},但set1 = {[1, 2]}卻會報錯。
- >>> set1 = {[1, 2]}
- Traceback (most recent call last):
- File "<pyshell#17>", line 1, in <module>
- set1 = {[1, 2]}
- TypeError: unhashable type: 'list'
從報錯資訊上我們看到“列表不是可雜湊型別”,沒錯,列表是可變的,它怎麼可以雜湊呢?!咦,等等,這句話好像在那聽過……呃,敢情集合跟字典的儲存方式一樣的丫!
其實你再想想就會覺得很有道理,利用雜湊函式計算,相同的元素得到的雜湊值(存放地址)是相同的,所以在集合中所有相同的元素都會覆蓋掉,因此有了集合的唯一性。
然後你繼續接著想就覺得更有道理了,通過雜湊函式計算的地址不可能是按順序排放的,所以集合才強調是無序的!
5. 開啟你的IDLE,輸入set1 = {1, 1.0},你發現了什麼?
答:沒錯, 集合內容是{1.0},其實你弄懂了上一題,這一題一樣容易:因為在Python的雜湊函式會將相同的值的元素計算得到相同的地址,所以1和1.0是等值的^_^
6. 請問如何給集合新增和刪除元素?
答:使用add()方法可以為集合新增元素,使用remove()方法可以刪除集合中已知的元素。
- >>> num1.add(6)
- >>> num1
- {0, 1, 2, 3, 4, 5, 6}
- >>> num1.remove(6)
- >>> num1
- {0, 1, 2, 3, 4, 5}
動動手
0. 自學擴充套件:自己花點時間看下這個表格(http://bbs.fishc.com/thread-45276-1-1.html),今後會用上的^_^
由於集合型別不是我們教學的重點,所以課堂中小甲魚僅強調基本的使用方法,這裡幫大家把Python集合型別的所有內建方法做成一個總結表,以便供大家使用時參考。
集合型別內建方法總結
集合(s).方法名 |
等價符號 |
方法說明 |
s.issubset(t) | s <= t | 子集測試(允許不嚴格意義上的子集):s 中所有的元素都是 t 的成員 |
s < t | 子集測試(嚴格意義上):s != t 而且 s 中所有的元素都是 t 的成員 | |
s.issuperset(t) | s >= t | 超集測試(允許不嚴格意義上的超集):t 中所有的元素都是 s 的成員 |
s > t | 超集測試(嚴格意義上):s != t 而且 t 中所有的元素都是 s 的成員 | |
s.union(t) | s | t | 合併操作:s "或" t 中的元素 |
s.intersection(t) | s & t | 交集操作:s "與" t 中的元素 |
s.difference | s - t | 差分操作:在 s 中存在,在 t 中不存在的元素 |
s.symmetric_difference(t) | s ^ t | 對稱差分操作:s "或" t 中的元素,但不是 s 和 t 共有的元素 |
s.copy() | 返回 s 的拷貝(淺複製) | |
以下方法僅適用於可變集合 |
||
s.update | s |= t | 將 t 中的元素新增到 s 中 |
s.intersection_update(t) | s &= t | 交集修改操作:s 中僅包括 s 和 t 中共有的成員 |
s.difference_update(t) | s -= t | 差修改操作:s 中包括僅屬於 s 但不屬於 t 的成員 |
s.symmetric_difference_update(t) | s ^= t | 對稱差分修改操作:s 中包括僅屬於 s 或僅屬於 t 的成員 |
s.add(obj) | 加操作:將 obj 新增到 s | |
s.remove(obj) | 刪除操作:將 obj 從 s 中刪除,如果 s 中不存在 obj,將引發異常 | |
s.discard(obj) | 丟棄操作:將 obj 從 s 中刪除,如果 s 中不存在 obj,也沒事兒^_^ | |
s.pop() | 彈出操作:移除並返回 s 中的任意一個元素 | |
s.clear() | 清除操作:清除 s 中的所有元素 |
1.本節課回顧
>>> num = {}
>>> type(num)
<class 'dict'>
>>> num2 = {1, 2, 3, 4}
>>> type(num2)
<class 'set'>
大括號並不是字典的特權,在Python裡,如果用大括號括起一堆沒有對映關係的數字時,這一堆數字就是集合。
集合的特點:(唯一)
>>> num = {1, 1, 2, 2, 3, 4}
>>> num
{1, 2, 3, 4}
集合和字典一樣,都是無序的,不支援index。
如何建立一個集合:
一種是直接把一堆元素用大括號括起來
一種是使用工廠函式set()
>>> set1 = set([1, 2, 2, 3, 4])
>>> set1
{1, 2, 3, 4}
>>> set1 = set('I love you')
>>> set1
{'I', 'v', 'e', 'o', 'y', 'u', ' ', 'l'}
搞搞看:去除列表中重複的元素:
[0, 1, 2, 3, 4, 5, 5, 3, 1]
如果沒學習集合,我們會:
>>> num = [0, 1, 2, 3, 4, 5, 5, 3, 1]
>>> temp = []
>>> for each in num:
if each not in temp:
temp.append(each)
>>> temp
[0, 1, 2, 3, 4, 5]
使用集合,如下:
>>> num = [0, 1, 2, 3, 4, 5, 5, 3, 1]
>>> num = list(set(num))
>>> num
[0, 1, 2, 3, 4, 5]
但是要注意,使用集合得到的是無序的。
如何訪問集合中的值:
可以使用for把集合中的資料一個個讀取出來
可以通過in 和 not in 判斷一個元素是否在集合中已經存在。
內建函式 add() 和 remove()
>>> num = {0, 1, 2, 3, 4, 5}
>>> num.add(6)
>>> num
{0, 1, 2, 3, 4, 5, 6}
>>> num.remove(1)
>>> num
{0, 2, 3, 4, 5, 6}
不可變集合
frozen:冰凍的,凍結的
frozenset() 定義不可變集合
>>> num = frozenset((1, 2, 3, 4, 5))
>>> num
frozenset({1, 2, 3, 4, 5})
>>> num.add(0)
Traceback (most recent call last):
File "<pyshell#34>", line 1, in <module>
num.add(0)
AttributeError: 'frozenset' object has no attribute 'add'