python中set和frozenset詳解

set(可變集合)與frozenset(不可變集合)的區別
set無序排序且不重複,是可變的,有add(),remove()等方法。既然是可變的,所以它不存在哈希值。基本功能包括關係測試和消除重複元素. 集合對象還支持union(聯合), intersection(交集), difference(差集)和sysmmetric difference(對稱差集)等數學運算. 
sets 支持 x in set, len(set),和 for x in set。作爲一個無序的集合,sets不記錄元素位置或者插入點。因此,sets不支持 indexing, 或其它類序列的操作。
frozenset是凍結的集合,它是不可變的,存在哈希值,好處是它可以作爲字典的key,也可以作爲其它集合的元素。缺點是一旦創建便不能更改,沒有add,remove方法。


一、集合的創建

set()和 frozenset()工廠函數分別用來生成可變和不可變的集合。如果不提供任何參數,默認
會生成空集合。如果提供一個參數,則該參數必須是可迭代的,即,一個序列,或迭代器,或支持
迭代的一個對象,例如:一個列表或一個字典。

複製代碼
 1 >>> s=set('cheeseshop')  使用工廠方法創建
 2 >>> s
 3 {'h', 'c', 'o', 's', 'e', 'p'}
 4 >>> type(s)
 5 <type 'set'>
 6 
 7 >>> s={'chessseshop','bookshop'}直接創建,類似於list的[]和dict的{},不同於dict的是其中的值,set會將其中的元素轉換爲元組
 8 >>> s
 9 {'bookshop', 'chessseshop'}
10 >>> type(s)
11 <type 'set'>
12 
13 不可變集合創建:
14 >>> t=frozenset('bookshop')
15 >>> t
16 frozenset({'h', 'o', 's', 'b', 'p', 'k'})
複製代碼

二、更新可變集合

用各種集合內建的方法和操作符添加和刪除集合的成員:

複製代碼
 1 >>> s.add('z')  #添加
 2 >>> s
 3 set(['c', 'e', 'h', 'o', 'p', 's', 'z'])
 4 >>> s.update('pypi') #添加
 5 >>> s
 6 set(['c', 'e', 'i', 'h', 'o', 'p', 's', 'y', 'z'])
 7 >>> s.remove('z') #刪除
 8 >>> s
 9 set(['c', 'e', 'i', 'h', 'o', 'p', 's', 'y'])
10 >>> s -= set('pypi')#刪除
11 >>> s
12 set(['c', 'e', 'h', 'o', 's'])
13 >>> del s  #刪除集合
複製代碼

只有可變集合能被修改。試圖修改不可變集合會引發異常。

1 >>> t.add('z')
2 Traceback (most recent call last):
3 File "<stdin>", line 1, in ?
4 AttributeError: 'frozenset' object has no attribute 'add'

三、成員關係 (in, not in)

1 >>> 'k' in s
2 False
3 >>> 'k' in t
4 True
5 >>> 'c' not in t
6 True

四、集合等價/不等價

複製代碼
1 >>> s == t
2 False
3 >>> s != t
4 True
5 >>> u = frozenset(s)
6 >>> s == u
7 True
8 >>> set('posh') == set('shop')
9 True
複製代碼

五、子集/超集

1 >>> set('shop') < set('cheeseshop')
2 True
3 >>> set('bookshop') >= set('shop')
4 True

六、遍歷訪問集合中的值(可變集合和非可變都支持)

複製代碼
 1 >>> s=set('cheeseshop')
 2 >>> s
 3 {'h', 'c', 'o', 's', 'e', 'p'}
 4 >>> for i in s:
 5     print(i)    
 6 h
 7 c
 8 o
 9 s
10 e
11 p
12 
13 
14 >>> t=frozenset('bookshop')
15 >>> t
16 frozenset({'h', 'o', 's', 'b', 'p', 'k'})
17 >>> for i in t:
18     print(i)    
19 h
20 o
21 s
22 b
23 p
24 k
複製代碼

七、集合類型操作符(所有的集合類型)

1.聯合( | )

1 兩個集合的聯合是一個新集合,該集合中的每個元素都至少是其中一個集合的成員,即,屬於兩個集合其中之一的成員。聯合符號有一個等價的方法,union().
2 >>> s | t
3 set(['c', 'b', 'e', 'h', 'k', 'o', 'p', 's'])

2.交集( & )

1 你可以把交集操作比做集合的 AND(或合取)操作。兩個集合的交集是一個新集合,該集合中的每
2 個元素同時是兩個集合中的成員,即,屬於兩個集合的成員。交集符號有一個等價的方法,intersection()
3 >>> s & t
4 set(['h', 's', 'o', 'p']

3.差補/相對補集( – )

1 兩個集合(s 和 t)的差補或相對補集是指一個集合 C,該集合中的元素,只屬於集合 s,而不屬
2 於集合 t。差符號有一個等價的方法,difference().
3 >>> s - t
4 set(['c', 'e'])

4.對稱差分( ^ )

1 和其他的布爾集合操作相似, 對稱差分是集合的 XOR(又稱"異或 ").
2 兩個集合(s 和 t)的對稱差分是指另外一個集合 C,該集合中的元素,只能是屬於集合 s 或者集合 t
3 的成員,不能同時屬於兩個集合。對稱差分有一個等價的方法,symmetric_difference().
4 >>> s ^ t
5 set(['k', 'b', 'e', 'c'])

5.混合集合類型操作

複製代碼
1 上面的示例中,左邊的 s 是可變集合,而右邊的 t 是一個不可變集合. 注意上面使用集合操作
2 運算符所產生的仍然是可變集合,但是如果左右操作數的順序反過來,結果就不一樣了:
3 >>> t | s
4 frozenset(['c', 'b', 'e', 'h', 'k', 'o', 'p', 's'])
5 >>> t ^ s
6 frozenset(['c', 'b', 'e', 'k'])
7 >>> t - s frozenset(['k', 'b'])
複製代碼

如果左右兩個操作數的類型相同, 既都是可變集合或不可變集合, 則所產生的結果類型是相同
的,但如果左右兩個操作數的類型不相同(左操作數是 set,右操作數是 frozenset,或相反情況),
所產生的結果類型與左操作數的類型相同

八、可變集合類型的方法

 

複製代碼
 1 s.update(t) 用 t 中的元素修改 s, 即,s 現在包含 s 或 t 的成員
 2 s.intersection_update(t) s 中的成員是共同屬於 s 和 t 的元素。
 3 s.difference_update(t) s 中的成員是屬於 s 但不包含在 t 中的元素
 4 s.symmetric_difference_update(t) s 中的成員更新爲那些包含在 s 或 t 中,但不 是 s
 5 和 t 共有的元素
 6 s.add(obj) 在集合 s 中添加對象 obj
 7 s.remove(obj) 從集合 s 中刪除對象 obj;如果 obj 不是集合 s 中的元素(obj not
 8 in s),將引發 KeyError 錯誤
 9 s.discard(obj) 如果 obj 是集合 s 中的元素,從集合 s 中刪除對象 obj;
10 s.pop() 刪除集合 s 中的任意一個對象,並返回它
11 s.clear() 刪除集合 s 中的所有元素
複製代碼

九、集合類型操作符、函數和方法

函數/方法名 等價運算符 說明
所有集合類型

複製代碼
 1 len(s) 集合基數: 集合 s 中元素的個數
 2 set([obj]) 可變集合工廠函數; obj 必須是支持迭代的,由 obj 中
 3 的元素創建集合,否則創建一個空集合
 4 frozenset([obj]) 不可變集合工廠函數; 執行方式和 set()方法相同,
 5 但它返回的是不可變集合
 6 obj in s 成員測試:obj 是 s 中的一個元素嗎?
 7 obj not in s 非成員測試:obj 不是 s 中的一個元素嗎?
 8 s == t 等價測試: 測試 s 和 t 是否具有相同的元素?
 9 s != t 不等價測試: 與==相反
10 s < t (嚴格意義上)子集測試; s != t 而且 s 中 所 有
11 的元素都是 t 的成員
12 s.issubset(t) s <= t 子集測試(允許不嚴格意義上的子集): s 中所有的元素
13 都是 t 的成員
14 s > t (嚴格意義上)超集測試: s != t 而且 t 中所有的元素
15 都是 s 的成員
16 s.issuperset(t) s >= t 超集測試(允許不嚴格意義上的超集): t 中所有的元素
17 都是 s 的成員
18 s.union(t) s | t 合併操作: s 或 t 中的元素
19 s.intersec- tion(t) s & t 交集操作: s 和 t 中的元素
20 s.difference(t) s - t 差分操作: s 中的元素,而不是 t 中的元素
21 s.symmetric_difference(t)s ^ t 對稱差分操作:s 或 t 中的元素,但不是 s 和 t 共有
22 的元素
23 s.copy() 複製操作:返回 s 的(淺複製)副本
複製代碼

僅用於可變集合:

複製代碼
 1 s.update(t) s |= t (Union) 修改操作: 將 t 中的成員添加 s
 2 s.intersection_update(t) s &= t 交集修改操作: s 中僅包括 s 和 t 中共有的成員
 3 s.difference_update(t) s -= t 差修改操作: s 中包括僅屬於 s 但不屬於 t 的成員
 4 s.symmetric_
 5 difference_
 6 update(t) s ^= t 對稱差分修改操作: s 中包括僅屬於 s 或僅屬於 t 的
 7 成員
 8 s.add(obj) 加操作: 將 obj 添加到 s
 9 s.remove(obj) 刪除操作: 將 obj 從 s 中刪除;如果 s 中不存在
10 obj,將引發 KeyError
11 s.discard(obj) 丟棄操作: remove() 的 友 好 版 本 -12 果 s 中存在 obj,
13 從 s 中刪除它
14 s.pop() Pop 操作: 移除並返回 s 中的任意一個元素
15 s.clear() 清除操作: 移除 s 中的所有元素
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章