python資料結構set

hiekay發表於2018-10-23

建立set

tuple算是list和str的雜合,那麼set則可以堪稱是list和dict的雜合.
set擁有類似dict的特點:可以用{}花括號來定義;其中的元素沒有序列,也就是是非序列型別的資料;而且,set中的元素不可重複,這就類似dict的鍵.
set也有繼承了一點list的特點:如可以原處修改(事實上是一種類別的set可以原處修改,另外一種不可以).

  • 實驗:
>>> s1 = set("hiekaye")  #把str中的字元拆解開,形成set.特別注意觀察:hiekay3中有兩個e
>>> s1                  #但是在s1中,只有一個i,也就是不能重複
set([`h`, `i`, `3`, `k`, `a`,`y`])

>>> s2 = set([123,"google","face","book","facebook","book"])    #通過list建立set.不能有重複,元素可以是int/str
>>> s2
set([`facebook`, 123, `google`, `book`, `face`])                #元素順序排列不是按照指定順序

>>> s3 = {"facebook",123}       #通過{}直接建立
>>> s3
set([123, `facebook`])
  • 探究:
>>> s3 = {"facebook",[1,2,`a`],{"name":"python","lang":"english"},123}
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unhashable type: `dict`

>>> s3 = {"facebook",[1,2],123}
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unhashable type: `list`

從上述實驗中,可以看出,通過{}無法建立含有list/dict元素的set.

  • 繼續探索:
>>> s1
set([`q`, `i`, `s`, `r`, `w`])
>>> s1[1] = "I"
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: `set` object does not support item assignment

>>> s1
set([`q`, `i`, `s`, `r`, `w`])
>>> lst = list(s1)
>>> lst
[`q`, `i`, `s`, `r`, `w`]
>>> lst[1] = "I"
>>> lst
[`q`, `I`, `s`, `r`, `w`]

上面的探索中,將set和list做了一個對比,雖然說兩者都能夠做原處修改,但是,通過索引編號(偏移量)的方式,直接修改,list允許,但是set報錯.
那麼,set如何修改呢?

更改set

  • 把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__`, `__sizeof__`, `__str__`, `__sub__`, `__subclasshook__`, `__xor__`, `add`, `clear`, `copy`, `difference`, `difference_update`, `discard`, `intersection`, `intersection_update`, `isdisjoint`, `issubset`, `issuperset`, `pop`, `remove`, `symmetric_difference`, `symmetric_difference_update`, `union`, `update`]

先看這些:

`add`, `clear`, `copy`, `difference`, `difference_update`, `discard`, `intersection`, `intersection_update`, `isdisjoint`, `issubset`, `issuperset`, `pop`, `remove`, `symmetric_difference`, `symmetric_difference_update`, `union`, `update`

然後用help()可以找到每個函式的具體使用方法,下面列幾個例子:

增加元素

>>> help(set.add)

Help on method_descriptor:

add(...)
Add an element to a set.
This has no effect if the element is already present.
  • 實驗:
>>> a_set = {}              #我想當然地認為這樣也可以建立一個set
>>> a_set.add("hiekay")     #報錯.看看錯誤資訊,居然告訴我dict沒有add.我分明建立的是set呀.
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: `dict` object has no attribute `add`
>>> type(a_set)             #type之後發現,計算機認為我建立的是一個dict
<type `dict`>

特別說明一下,{}這個東西,在dict和set中都用.但是,如上面的方法建立的是dict,不是set.這是python規定的.要建立set,只能用前面介紹的方法了.

>>> a_set = {`a`,`i`}       #這回就是set了吧
>>> type(a_set)
  <type `set`>              #果然

>>> a_set.add("hiekay")     #增加一個元素
>>> a_set                   #原處修改,即原來的a_set引用物件已經改變
set([`i`, `a`, `hiekay`])

>>> b_set = set("python")
>>> type(b_set)
<type `set`>
>>> b_set
set([`h`, `o`, `n`, `p`, `t`, `y`])
>>> b_set.add("hiekay")
>>> b_set
set([`h`, `o`, `n`, `p`, `t`, `hiekay`, `y`])

>>> b_set.add([1,2,3])      #這樣做是不行滴,跟前面一樣,報錯.
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unhashable type: `list`

>>> b_set.add(`[1,2,3]`)    #可以這樣!
>>> b_set
set([`[1,2,3]`, `h`, `o`, `n`, `p`, `t`, `hiekay`, `y`])

從另外一個set中合併過來元素,方法是set.update(s2)

>>> help(set.update)
update(...)
    Update a set with the union of itself and others.

>>> s1
set([`a`, `b`])
>>> s2
set([`github`, `hiekay`])
>>> s1.update(s2)       #把s2的元素併入到s1中.
>>> s1                  #s1的引用物件修改
set([`a`, `hiekay`, `b`, `github`])
>>> s2                  #s2的未變
set([`github`, `hiekay`])

刪除

>>> help(set.pop)
pop(...)
    Remove and return an arbitrary set element.
    Raises KeyError if the set is empty.

>>> b_set
set([`[1,2,3]`, `h`, `o`, `n`, `p`, `t`, `hiekay`, `y`])
>>> b_set.pop()     #從set中任意選一個刪除,並返回該值
`[1,2,3]`
>>> b_set.pop()
`h`
>>> b_set.pop()
`o`
>>> b_set
set([`n`, `p`, `t`, `hiekay`, `y`])

>>> b_set.pop("n")  #如果要指定刪除某個元素,報錯了.
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: pop() takes no arguments (1 given)

set.pop()是從set中任意選一個元素,刪除並將這個值返回.但是,不能指定刪除某個元素.報錯資訊中就告訴我們了,pop()不能有引數.此外,如果set是空的了,也報錯.這條是幫助資訊告訴我們的.

  • 要刪除指定的元素,怎麼辦?
>>> help(set.remove)

remove(...)
    Remove an element from a set; it must be a member.

    If the element is not a member, raise a KeyError.

set.remove(obj)中的obj,必須是set中的元素,否則就報錯.試一試:

>>> a_set
set([`i`, `a`, `hiekay`])
>>> a_set.remove("i")
>>> a_set
set([`a`, `hiekay`])
>>> a_set.remove("w")
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
KeyError: `w`
  • discard(obj):
>>> help(set.discard)

discard(...)
    Remove an element from a set if it is a member.

    If the element is not a member, do nothing.

與help(set.remove)的資訊對比,看看有什麼不同.discard(obj)中的obj如果是set中的元素,就刪除,如果不是,就什麼也不做,do nothing.

>>> a_set.discard(`a`)
>>> a_set
set([`hiekay`])
>>> a_set.discard(`b`)
>>>
  • set.clear(),它的功能是:Remove all elements from this set.
>>> a_set
set([`hiekay`])
>>> a_set.clear()
>>> a_set
set([])
>>> bool(a_set)     #空了,bool一下返回False.
False


相關文章