1. 程式人生 > 實用技巧 >Python內建資料結構--------set集合

Python內建資料結構--------set集合

set性質

可變的、無序的、不重複的元素的集合

set定義和初始化

語法:

  • set() -> 空集合
  • set(iterable) -> set物件
In [2]: s1=set()

In [3]: s1
Out[3]: set()

In [4]: s2=set(range(5))

In [5]: s2
Out[5]: {0, 1, 2, 3, 4}
In [6]: s1=set(enumerate(range(5)))

In [7]: s1
Out[7]: {(0, 0), (1, 1), (2, 2), (3, 3), (4, 4)}

In [9]: s2={(1,2
),'b',None,True,b'abc'}

set中的元素必須可hash(可變型別基本都不可雜湊)

In [12]: s3={bytearray(b'ab'),{1},'a'}
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-12-c756f10834fb> in <module>
----> 1
s3={bytearray(b'ab'),{1},'a'} TypeError: unhashable type: 'bytearray' In [8]: s2={(1,2),[1,'a',(4,1)],'b',None,True,b'abc'} --------------------------------------------------------------------------- TypeError Traceback (most recent call last) <ipython-input-8-984c42c3f9da> in
<module> ----> 1 s2={(1,2),[1,'a',(4,1)],'b',None,True,b'abc'} TypeError: unhashable type: 'list' In [11]: s3={{1},'a'} --------------------------------------------------------------------------- TypeError Traceback (most recent call last) <ipython-input-11-18225384901d> in <module> ----> 1 s3={{1},'a'} TypeError: unhashable type: 'set'

set方法

set增加元素

add(element)

In [19]: s.add(range(5))

In [20]: s
Out[20]: {1, range(0, 5)}

In [22]: s.add(tuple(range(5)))

In [23]: s
Out[23]: {(0, 1, 2, 3, 4), 1, range(0, 5)}

update(*others) 將其他可迭代物件的元素到本集合中,就地修改

In [25]: s
Out[25]: {(0, 1, 2, 3, 4), 1, range(0, 5)}

In [26]: s.update({1,2})

In [27]: s
Out[27]: {(0, 1, 2, 3, 4), 1, 2, range(0, 5)}

In [28]: s.update({1,2},{2,1,3})

In [29]: s
Out[29]: {(0, 1, 2, 3, 4), 1, 2, 3, range(0, 5)}

set刪除元素

remove(elem) 移除一個元素,如果元素不存在,丟擲KeyError異常

In [32]: s.remove(1)

In [33]: s
Out[33]: {(0, 1, 2, 3, 4), 2, 3, 5, range(0, 5)}

In [34]: s.remove(10)
---------------------------------------------------------------------------
KeyError                                  Traceback (most recent call last)
<ipython-input-34-23b5f1bb77c8> in <module>
----> 1 s.remove(10)

KeyError: 10

discard(elem) 移除一個元素,如果元素不存在,不拋異常

In [35]: s
Out[35]: {(0, 1, 2, 3, 4), 2, 3, 5, range(0, 5)}

In [36]: s.discard(10)

In [37]: s
Out[37]: {(0, 1, 2, 3, 4), 2, 3, 5, range(0, 5)}

In [38]: s.discard(2)

In [39]: s
Out[39]: {(0, 1, 2, 3, 4), 3, 5, range(0, 5)}

pop() ->item 移除任意一個元素,並返回該元素,如果沒有元素,返回KeyError

In [39]: s
Out[39]: {(0, 1, 2, 3, 4), 3, 5, range(0, 5)}

In [40]: s.pop()
Out[40]: range(0, 5)

In [41]: s.pop()
Out[41]: 3

In [42]: s.pop()
Out[42]: (0, 1, 2, 3, 4)

In [43]: s.pop()
Out[43]: 5

In [44]: s.pop()
---------------------------------------------------------------------------
KeyError                                  Traceback (most recent call last)
<ipython-input-44-c88c8c48122b> in <module>
----> 1 s.pop()

KeyError: 'pop from an empty set'

clear() 移除所有元素

In [45]: s2
Out[45]: {(1, 2), None, True, 'b', b'abc'}

In [46]: s2.clear()

In [47]: s2
Out[47]: set()

set沒有修改操作,要麼增加,要麼刪除,set可以遍歷,但不能被索引

set成員運算子比較和效率問題

列表的成員運算

In [53]: %%timeit lst1=list(range(100))
    ...: -1 in lst1
    ...:
    ...:
812 ns ± 31.2 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)

In [54]: %%timeit lst2=list(range(10000))
    ...: -1 in lst2
    ...:
    ...:
78.3 µs ± 624 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)

集合的成員運算

In [51]: %%timeit s1=set(range(100))
    ...: -1 in s1
    ...:
    ...:
24 ns ± 0.159 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)

In [52]: %%timeit s2=set(range(10000))
    ...: -1 in s2
    ...:
    ...:
24.1 ns ± 0.247 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each)

集合運算

並集:將多個集合的元素合併到一起

union(*other) 返回多個可迭代物件合併後的新集合

In [55]: s1
Out[55]: {(0, 0), (1, 1), (2, 2), (3, 3), (4, 4)}

In [56]: s2
Out[56]: set()

In [57]: s2={1,2,'abc'}

In [58]: s1.union(s2)
Out[58]: {(0, 0), (1, 1), (2, 2), (3, 3), (4, 4), 1, 2, 'abc'}

In [60]: s1.union((3,b'abc'),{'a','b'})
Out[60]: {(0, 0), (1, 1), (2, 2), (3, 3), (4, 4), 3, 'a', 'b', b'abc'}

| 運算子過載 和 union相似

In [64]: s1|s2
Out[64]: {(0, 0), (1, 1), (2, 2), (3, 3), (4, 4), 1, 2, 'abc'}

update(*others) 前面寫過了,就地修改

|= 和update相似

In [65]: s1|=s2

In [66]: s1
Out[66]: {(0, 0), (1, 1), (2, 2), (3, 3), (4, 4), 1, 2, 'abc'}

In [67]: s2
Out[67]: {1, 2, 'abc'}

交集:求兩個集合中相同的元素

intersection(*others) 返回多個集合的交集

In [25]: s1
Out[25]: {(0, 0), (1, 1), (2, 2), (3, 3), (4, 4), 1, '1', 2, '2', '3', 'abc'}

In [26]: s2
Out[26]: {(2, 2), 1, 2, 'abc'}

In [27]: s3
Out[27]: {'abc'}

In [28]: s1.intersection(s2,s3)
Out[28]: {'abc'}

intersection_update(*others)

In [29]: s1.intersection_update(s2)

In [30]: s1
Out[30]: {(2, 2), 1, 2, 'abc'}

& 等價intersection

In [31]: s1 & s2
Out[31]: {(2, 2), 1, 2, 'abc'}

&= 等價intersection_update

In [35]: s1 &=s3

In [37]: s3
Out[37]: {'abc'}

In [36]: s1
Out[36]: {'abc'}

差集:獲取多個集合中不同的元素組成的集合

difference(*ohters)

In [38]: s1={(0, 0), (1, 1), (2, 2), (3, 3), (4, 4), 1, '1', 2, '2', '3', 'abc'}

In [39]: s2
Out[39]: {(2, 2), 1, 2, 'abc'}

In [40]: s3
Out[40]: {'abc'}

In [41]: s1.difference(s3)
Out[41]: {(0, 0), (1, 1), (2, 2), (3, 3), (4, 4), 1, '1', 2, '2', '3'}

difference_update(*others)

In [45]: s1.difference_update(s3)

In [46]: s1
Out[46]: {(0, 0), (1, 1), (2, 2), (3, 3), (4, 4), 1, '1', 2, '2', '3'}

"-" 等價於difference

In [49]: s1
Out[49]: {(0, 0), (1, 1), (2, 2), (3, 3), (4, 4), 1, '1', 2, '2', '3'}

In [50]: s2
Out[50]: {(2, 2), 1, 2, 'abc'}

In [51]: s1 - s2
Out[51]: {(0, 0), (1, 1), (3, 3), (4, 4), '1', '2', '3'}

"-=" 等價於difference_update

In [49]: s1
Out[49]: {(0, 0), (1, 1), (2, 2), (3, 3), (4, 4), 1, '1', 2, '2', '3'}

In [50]: s2
Out[50]: {(2, 2), 1, 2, 'abc'}

In [51]: s1 - s2
Out[51]: {(0, 0), (1, 1), (3, 3), (4, 4), '1', '2', '3'}

In [52]: s1.difference_update(s2)

In [53]: s1
Out[53]: {(0, 0), (1, 1), (3, 3), (4, 4), '1', '2', '3'}

對稱差集:獲取兩個集合的差集,等價於(s1 -s2) ∪(s2-s1)

symmetric_difference(other)

In [55]: s1
Out[55]: {(0, 0), (1, 1), (3, 3), (4, 4), '1', '2', '3'}

In [56]: s2
Out[56]: {(2, 2), 1, 2, 'abc'}

In [57]: s1.symmetric_difference(s2)
Out[57]: {(0, 0), (1, 1), (2, 2), (3, 3), (4, 4), 1, '1', 2, '2', '3', 'abc'}

symmetric_difference_update(other)

In [62]: s1={(0, 0), (1, 1), (2, 2), (3, 3), (4, 4), 1, '1', 2, '2', '3', 'abc'}

In [63]: s2
Out[63]: {(2, 2), 1, 2, 'abc'}

In [64]: s1.symmetric_difference_update(s2)
Out[64]: {(0, 0), (1, 1), (3, 3), (4, 4), '1', '2', '3'}

"^" 等價於symmetric_difference(other)

In [67]:  s1={(0, 0), (1, 1), (2, 2), (3, 3), (4, 4), 1, '1', 2, '2', '3', 'abc'}

In [68]: s2
Out[68]: {(2, 2), 1, 2, 'abc'}

In [69]: s1 ^ s2
Out[69]: {(0, 0), (1, 1), (3, 3), (4, 4), '1', '2', '3'}

"^=" 等價於symmetric_difference_update(other)

In [70]: s1 ^= s2

In [71]: s1
Out[71]: {(0, 0), (1, 1), (3, 3), (4, 4), '1', '2', '3'}

集合判斷

issubset(other) , <= 判斷某個集合是否是另一個集合的子集

In [75]: s1={(0, 0), (1, 1), (2, 2), (3, 3), (4, 4), 1, '1', 2, '2', '3', 'abc'}

In [76]: s2
Out[76]: {(2, 2), 1, 2, 'abc'}

In [77]: s1 <= s2
Out[77]: False

In [78]: s1.issubset(s2)
Out[78]: False

In [79]: s2.issubset(s1)
Out[79]: True

set1 < set2 判斷set1是否是set2的真子集

In [80]: s2 < s1
Out[80]: True

In [81]: s1 < s2
Out[81]: False

issuperset(other)、>= 判斷集合是否是other集合的超集

In [3]: s1.issuperset(s2)
Out[3]: True

In [4]: s2>=s1
Out[4]: False

set1 > set2 判斷set1是否是set2的真超集

In [5]: s2 > s1
Out[5]: False

isdisjoint(other) 當前集合和other集合是否有交集,沒有則返回True

In [5]: s2 > s1
Out[5]: False