Python內置類型——set


Python中,內置類型set和frozenset用來表示集合,我們首先查看這兩個類型支持的特殊對象,從而可以理解他們的特性。

>>> dir(set)
['__and__', '__class__', '__cmp__', '__contains__', '__delattr__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__iand__', '__init__', '__ior__', '__isub__', '__iter__', '__ixor__', '__le__', '__len__', '__lt__', '__ne__', '__new__', '__or__', '__rand__', '__reduce__', '__reduce_ex__', '__repr__', '__ror__', '__rsub__', '__rxor__', '__setattr__', '__sizeof__', '__str__', '__sub__', '__subclasshook__', '__xor__', ...]
>>>
>>> dir(frozenset)
['__and__', '__class__', '__cmp__', '__contains__', '__delattr__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__iter__', '__le__', '__len__', '__lt__', '__ne__', '__new__', '__or__', '__rand__', '__reduce__', '__reduce_ex__', '__repr__', '__ror__', '__rsub__', '__rxor__', '__setattr__', '__sizeof__', '__str__', '__sub__', '__subclasshook__', '__xor__', ...]

 

set類型支持:

  • x in s :判斷x是否在s中,因為set對象支持特殊方法__contains__()
  • len(s):計算set對象中元素的個數,因為set對象支持特殊方法__len__()
  • for x in s :遍歷s,即s是可迭代的,因為set對象支持特殊方法__iter__()

set類型的對象不支持:

  • 索引(indexing):試圖執行s[0]之類的操作將會拋出異常TypeError
  • 切片(slice):試圖執行s[:]之類的操作將會拋出異常TypeError,因為可以看到set類型並不支持特殊方法__getitem__()
  • 哈希(hash):因為set對象的__hash__()方法是None,等於不支持。

此外,Python中另一個重要的內置類型是frozenset:

  • frozenset對象是不可變的(即不支持set對象的那些 mutating 方法)
  • frozenset對象有哈希值(從而可以作為字典的鍵和其他set對象的元素)。

 

例1. frozenset類型支持的非特殊方法

>>> dir(frozenset)
[..., 'copy', 'difference', 'intersection', 'isdisjoint', 'issubset', 'issuperset', 'symmetric_difference', 'union']
>>> dir(set)
[..., 'add', 'clear', 'copy', 'difference', 'difference_update', 'discard', 'intersection', 'intersection_update', 'isdisjoint', 'issubset', 'issuperset', 'pop', 'remove', 'symmetric_difference', 'symmetric_difference_update', 'union', 'update']

  可見frozenset支持與set相同的non-mutating方法,而set支持的可變方法,frozenset則不支持。

  

例2. 對frozenset與set類型進行哈希運算的結果

>>> s1 = frozenset('123')
>>> s2 = set('123')
>>> hash(s1)
-98267375
>>> hash(s2)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unhashable type: 'set'

  可見frozenset是hashable對象,可以作為字典的鍵

 

例3. 將frozenset和set實例作字典鍵

>>> d= {s1:1}
>>> d= {s2:2}
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unhashable type: 'set'

 

例4. 為什么set對象是不可哈希的

>>> dir(set)
['__and__', '__class__', '__cmp__', '__contains__', '__delattr__', '__doc__', '__eq__', '__format__
, '__ge__', '__getattribute__', '__gt__', '__hash__', '__iand__', '__init__', '__ior__', '__isub__'
 '__iter__', '__ixor__', '__le__', '__len__', '__lt__', '__ne__', '__new__', '__or__', '__rand__',
__reduce__', '__reduce_ex__', '__repr__', '__ror__', '__rsub__', '__rxor__', '__setattr__', '__size
f__', '__str__', '__sub__', '__subclasshook__', '__xor__', 'add', 'clear', 'copy', 'difference', 'd
fference_update', 'discard', 'intersection', 'intersection_update', 'isdisjoint', 'issubset', 'issu
erset', 'pop', 'remove', 'symmetric_difference', 'symmetric_difference_update', 'union', 'update']
>>> type(set.__hash__)
<type 'NoneType'>

  我們看到,原來set對象沒有__hash__()方法(__hash__方法是個None對象),所以它並不支持哈希運算。

 

non-mutating方法

s.copy()

  返回集合s的淺拷貝。

 

s.difference(s1)

  返回集合s中不在集合s1中的元素的集合,即s-s1。

 

s.intersection(s1)

  返回s與s1的交集。即s&s1.

 

s.issubset(s1)

  判斷s是不是s1的子集。

 

s.issuperset(s1)

   判斷s是不是s1的超集。

 

s.symmetric_difference(s1)

   返回由要么在s中,要么在s1中,但不同時在s和s1中的元素組成的集合。即s^s1。

例:對稱差集

1 >>> s
2 set([1, 2, 3, 5])
3 >>> s1
4 set([1, 2, 3, 4])
5 >>> s.symmetric_difference(s1)
6 set([4, 5])

 

s.union(s1)

  返回s和s1的並集。即s|s1。

 

mutating 方法

s.add(x)

  將x添加到集合s中,如果s中已經有x,則該操作沒有影響。

 

s.clear()

  清空集合s。

 

s.discard(x)

  從集合s中刪除x,如果x不在s中,該操作沒有影響。

 

s.pop()

  返回並刪除集合s中的任意一個元素。

 

s.remove(x)

  區別於s.discard(x),當x在集合S中時,二者效果相同,但當x不在集合S中時,remove(x)拋出異常:KeyError;而discard(x)沒有影響。

 

s.difference_update(s1)

  即:s -= s1

s.intersection_update(s1)

  即:s &= s1

s.symmetric_difference_update(s1)

  即:s ^= s1

s.update(s1)

  即:s |= s1

  使用運算符進行集合的運算和使用函數的功能相同,當使用(增強)運算符時,兩端的運算數都得是set或frozenset,

  使用函數進行集合運算時,s1只要是元素可哈希的可迭代對象就行。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM