1. 程式人生 > >Python 3.7.1 基礎 資料型別 集合 set

Python 3.7.1 基礎 資料型別 集合 set

集合

一個集合物件是一個包含不同的可雜湊物件的無序集合。常見用途包括成員測試,從序列中刪除重複項,以及計算數學運算,如交集,並集,差異和對稱差異。

集合支援x in setlen(set)for x in set。作為無序集合,集合不記錄元素位置或插入順序。因此,集合不支援索引,切片或其他類似序列的行為。

目前有兩種內建集合型別,set和frozenset。
(1)set型別是可變的-內容可使用類似 add()和remove() 的方法來改變。由於它是可變的,因此它沒有雜湊值,不能用作字典鍵或另一個集合的元素。
(2)frozenset型別是不可變的和可雜湊的 - 其內容在建立後不能更改; 因此,它可以用作字典鍵或另一個集合的元素。

1. 構造

非空集合(非 frozensets)除了使用set()建構函式之外構造之外,還可以通過在大括號中放置以逗號分隔的元素列表來建立,例如:{'jack', 'sjoerd'}

兩個類的建構函式的工作方式相同:

class set([iterable])
class frozenset([iterable])

返回一個新的set或frozenset物件,其元素取自 iterable。集合的元素必須是可hash的。要表示集合包含集合,內部集合必須是frozenset 物件。如果未指定iterable,則返回新的空集。

譯者例項

def set_constructor():
    mst = set('abc')
    mst1 = set(list([1,2,3]))
    print(mst)
    print(mst1)
    mst2 = set(list([mst,mst1]))
    print(mst2)
# 輸出結果
{'a', 'c', 'b'}
{1, 2, 3}
Traceback (most recent call last):
File "xx/list1.py", line 233, in set_constructor
    mst2 = set(list([mst,mst1]))
TypeError: unhashable type: 'set'
def set_constructor2():
    mst3 = frozenset('abc')
    mst4 = frozenset(list([1, 2, 3]))
    mst5 = set(list([mst3, mst4]))
    print(mst5)
    print(type(mst5))
# 輸出結果
{frozenset({'b', 'c', 'a'}), frozenset({1, 2, 3})}
<class 'set'>

2. 方法

2.1 set 和 frozenset的公有操作:

len(s)

返回集合s的元素數個數(s的基數)。

x in s

測試x是s的成員。

x not in s

測試x不是s的成員。

isdisjoint(other)

如果set與other的交集不為空,則返回True。為空時,返回False

issubset(other) 或 set <= other

測試set是不是other的子集,是的話返回True,否則False

set < other

測試set是不是other的真子集 ( 即set <= other and set != other ) ,是的話返回True,否則False

def set_opt():
    set1 = set(list([1,2,3,4,5]))
    set2 = set(list([4, 5,6,7,8]))
    set3 = set(list([6, 7, 8,9,0]))
    set4 = set(list([1,2,3,4,5,6]))
    set5 = set(list([1,2,3,4,5]))
    print("len(set1):",len(set1))
    print("3 in set1:" ,3 in set1)
    print("3 in set2",3 in set2)
    print("set1.isdisjoint(set2):",set1.isdisjoint(set2))
    print("set1.isdisjoint(set3):",set1.isdisjoint(set3))
    print("set1.issubset(set2):", set1.issubset(set2))
    print("set1.issubset(set4):",set1.issubset(set4))
    print("set1<=set4:", set1<=set4)
    print("set1<=set5:", set1<=set5)
    print("set1<set5:", set1<set5)
# 輸出結果
len(set1): 5
3 in set1: True
3 in set2 False
set1.isdisjoint(set2): False
set1.isdisjoint(set3): True
set1.issubset(set2): False
set1.issubset(set4): True
set1<=set4: True
set1<=set5: True
set1<set5: False

issuperset(other) 或 set >= other

測試ohter集合是不是set的子集,是的話返回True,否則False。。

set > other

測試ohter集合是不是set的真子集(即set >= other and set != other),是的話返回True,否則False

union(*others) 或 set | other | …

返回set和other(可以指定多個other)的並集。

intersection(*others) 或 set & other & …

返回set和other(可以指定多個other)的交集。

difference(*others) 或 set - other - …

返回一個新集合,其中集合中的元素不在other(可以指定多個other)集合中。

symmetric_difference(other) 或 set ^ other ^ …

返回一個新集合,裡面的元素是兩者的並集減去交集的結果。

def set_opt2():
    set1 = set(list([1,2,3,4,5]))
    set2 = set(list([1,2,3]))
    set3 = set(list([4, 5,6,7,8]))
    print("set1.issuperset(set2):",set1.issuperset(set2))
    print("set1>=set2:",set1>=set2)
    print("set1.union(set2,set3):",set1.union(set2,set3))
    print("set1|set2|set3:",set1|set2|set3)
    print("set1&set2:",set1&set2)
    print("set1.intersection(set3,set2):",set1.intersection(set3,set2))
    print("set1.difference(set2):",set1.difference(set2))
    print("set3-set1-set2:",set3-set1-set2)
    print("set1^set3",set1^set3)
    set4 = set3.copy()
    print(id(set4),id(set3))
    set3.remove(4)
    print("set3:",set3,"set4:",set4)
# 輸出結果
set1.issuperset(set2): True
set1>=set2: True
set1.union(set2,set3): {1, 2, 3, 4, 5, 6, 7, 8}
set1|set2|set3: {1, 2, 3, 4, 5, 6, 7, 8}
set1&set2: {1, 2, 3}
set1.intersection(set3,set2): set()
set1.difference(set2): {4, 5}
set3-set1-set2: {8, 6, 7}
set1^set3 {1, 2, 3, 6, 7, 8}
20633280 20633160
set3: {5, 6, 7, 8} set4: {4, 5, 6, 7, 8}

copy()

返回一個帶有s的淺拷貝的新集合。


注意,引數為*other的那幾個函式將接受任何可迭代的引數。相比之下,他們的或版本(使用操作符如>=)要求他們的引數是集合。這排除了容易出錯的結構,例如 set('abc') & 'cbs'set('abc').intersection('cbs')更有可讀性。

set和frozenset都支援各自的比較。

set和frozenset進行比較的時候,根據自己的成員。例如set('abc') == frozenset('abc')返回Trueset('abc') in set([frozenset('abc')])也返回True

子集和相等比較不推廣到總排序函式(這句不知道怎麼翻he subset and equality comparisons do not generalize to a total ordering function)。例如,任何兩個非空不相交的集合不相等,那麼彼此的兩個子集一定不會相交,所以這幾個比較都返回False:a<ba==ba>b

由於集合僅定義了部分排序(子集關係),因此對於集合列表,list.sort()方法的輸出是未定義的。

set1 = set(list([1,2,3,4,5]))
set2 = set(list([1,2,3]))
set3 = set(list([4, 5,6,7,8]))
list1 = [set1,set2,set3]
print(list1)
print(list1.sort())
#輸出結果
[{1, 2, 3}, {1, 2, 3, 4, 5}, {5, 6, 7, 8}]
None

集合的元素(如字典鍵)必須是可雜湊的。

混合set和frozenset 的二進位制操作返回第一個集合的型別。例如frozenset('ab') | set('bc'):返回一個frozenset例項。


2.2 只適用於set的方法

update(*others) 或 set |= other | …

更新set集合,新增other中的所有元素。

intersection_update(*others) 或 set &= other & …

更新set集合,新增大家共有的所有元素。

difference_update(*others) 或 set -= other | …

更新set集合,移除set中的所有other中的元素。

symmetric_difference_update(other) 或 set ^= other

更新set集合,裡面的元素是兩者的並集減去交集的結果。

譯者注:本地測試|=,&=,-=,^=都會報錯,只能用對應的函式。

def set_opt3_not_for_fronzenset():
    set1 = set(list([1,2,3,4,5]))
    set2 = set(list([1,2,3]))
    set3 = set(list([4, 5,6,7,8]))
    print(set1.update(set2,set3))
    print("set1.update(set2,set3):",set1)
    print(set1.intersection_update(set2))
    print("set1.intersection_update(set2):",set1)
    set1 = set(list([1,2,3,4,5]))
    print(set3.difference_update(set1))
    print("set3.difference_update(set1)",set3)
    print(set1.symmetric_difference_update(set2))
    print("set1.symmetric_difference_update(set2)",set1)
# 輸出結果
None
set1.update(set2,set3): {1, 2, 3, 4, 5, 6, 7, 8}
None
set1.intersection_update(set2): {1, 2, 3}
None
set3.difference_update(set1) {6, 7, 8}
None
set1.symmetric_difference_update(set2) {4, 5}

add(elem)

將元素elem新增到集合中。

remove(elem)

從集合中刪除元素elem。如果elem未包含在集合中,則引發KeyError

discard(elem)

如果元素elem存在,則從集合中刪除元素elem。

pop()

從集合中刪除並返回任意元素。如果集合為空則引發KeyError

clear()

從集合中刪除所有元素。

def set_opt3_not_for_fronzenset2():
    set1 = set(list([1,2,3,4,5]))
    set1.add(9)
    set1.remove(3)
    set1.discard(100)
    print("set1:",set1)
    print("set1.pop():",set1.pop())
    set1.clear()
    print("set1.clear():",set1)
# 輸出結果
set1: {1, 2, 4, 5, 9}
set1.pop(): 1
set1.clear(): set()