2017-05-17

Java 腦袋學 Python Set

Python Set 概念上和 Java Set 一樣。
  • 無序
  • 唯一(去重複)
  • Hashable
Hashable 保證唯一,同時讓 set 和 list 比起來,新增快,查找快,常用 set 來去除 sequence 中重複的 item,或者檢查 item 是否存在。

Set 的 item 必須是 Hashable,像 dict 的 key 一樣,也就表示 set 的 item 必須是 immutable,所以不可以把 set 裝到 set 裡,目前知道 immutable 的集合物件只有 tuple 一個,很快就會出現另一個了,像 tuple 是 immutable 的 list 一樣,set 也有 immutable 的版本。

set() & {}

語法類似半套的 dict,用大括號,但只有 key,沒有 value。

s = {'a', 'A', 'a'}
print(s) # {'A', 'a'}
比較常用其他 sequence 來建立 set,同時去除重複。
s = 'Pineapple & Apple'
li1 = list(s)
print(len(li1)) # 17
print(li1) # ['P', 'i', 'n', 'e'...
print(sorted(li1)) # [' ', ' ', '&', 'A'...
s1 = set(s)
print(len(s1)) # 10
print(s1) # {'P', ' ', 'p', 'a', '&', 'A', 'l', 'i', 'e', 'n'}
print(sorted(s1)) # [' ', '&', 'A', 'P', 'a', 'e', 'i', 'l', 'n', 'p']
可以使用所有 sequence 和順序無關的操作,例如 len() 與 for-in,但是不能用 [N] 或者 slice。

set 的 method

除了使用 set() 與 {} 建立 set 外,也可以使用 set.add() 與 set.remove() 操作 set 裡的 item。
s1 = set('Apple')
print(s1) # {'p', 'A', 'l', 'e'}

s1.add('E')
print(s1) # {'E', 'p', 'e', 'l', 'A'}

s1.remove('p')
print(s1) # {'e', 'E', 'A', 'l'}
# s1.remove('X') # KeyError

s1.discard('X') # 同 remove() 但不存在不會報錯

print(s1.pop()) # e,任意丟出一個,如果 set 空了會丟出 KeyError

s1.clear() # 清空
print(s1) # set()

set item 比對

print('A' in set('Apple')) # True
print('p' not in set('Apple')) # False

print(set('Apple').isdisjoint(set('Banana'))) # True,兩個 set 沒有相同的 item,也就是交集為空

# 子集
print(set('Apple').issubset(set('Apple'))) # True,s <= other
print(set('Apple').issubset(set('PineApple'))) # True,s < =other
print(set('Apple') == set('Apple')) # True
print(set('Apple') <= set('PineApple')) # True

# 超集
print(set('PineApple').issuperset(set('Apple'))) # True,s >= other
print(set('PineApple') > set('Apple')) # True,s >= other

# 聯集
u1 = set('PineApple').union(set('Apple'))
u2 = set('PineApple') | set('Apple')
print(u1 == u2) # True
print(u1) # {'i', 'P', 'n', 'A', 'p', 'l', 'e'}

# 交集
u1 = set('PineApple').intersection(set('Apple'))
u2 = set('PineApple') & set('Apple')
print(u1 == u2) # True
print(u1) # {'p', 'e', 'l', 'A'}

# 差集
u1 = set('PineApple').difference(set('Apple'))
u2 = set('PineApple') - set('Apple')
print(u1 == u2) # True
print(u1) # {'i', 'P', 'n'}

# 對稱差集,只能一邊有,不能兩邊有,當然不會有兩邊都沒有
u1 = set('abc').symmetric_difference(set('bcd'))
u2 = set('abc') ^ set('bcd')
print(u1 == u2) # True
print(u1) # {'d', 'a'}

# 複製
s1 = set('Apple')
s2 = s1.copy()
s1.add('X')
print(s1) # {'A', 'p', 'l', 'e', 'X'}
print(s2) # {'l', 'A', 'p', 'e'}
特別的是 union()、intersection()、difference()、symmetric_difference()、issubset() 與 issuperset() 可以接受 iterable 參數,並不限制只能傳 set,但是相對應的運算子(==、>、>=、<、<=、!=、|、&、-、^、)就只能 set 對 set。

還有一點特別要注意的,並沒有 set + set 運算子,兩個 set 相加只能用 | 或者 union()。

frozenset() - immutable set

唯讀的 set,上面所有唯讀的操作都可以使用,也可以用在 dict 的 key,以及 set of frozenset。 
print(frozenset('Apple')) # frozenset({'l', 'p', 'e', 'A'})
官方文件
---
---
---

沒有留言:

張貼留言