回顧一下已經(jīng)學(xué)過(guò)的數(shù)據(jù)類(lèi)型:int/str/bool/list/dict/tuple
還真的不少了.
不過(guò),python是一個(gè)發(fā)展的語(yǔ)言,沒(méi)準(zhǔn)以后還出別的呢.看官可能有疑問(wèn)了,出了這么多的數(shù)據(jù)類(lèi)型,我也記不住呀,特別是里面還有不少方法.
不要擔(dān)心記不住,你只要記住愛(ài)因斯坦說(shuō)的就好了.
愛(ài)因斯坦在美國(guó)演講,有人問(wèn):“你可記得聲音的速度是多少?你如何記下許多東西?”
愛(ài)因斯坦輕松答道:“聲音的速度是多少,我必須查辭典才能回答。因?yàn)槲覐膩?lái)不記在辭典上已經(jīng)印著的東西,我的記憶力是用來(lái)記憶書(shū)本上沒(méi)有的東西?!?/p>
多么霸氣的回答,這回答不僅僅霸氣,更告訴我們一種方法:只要能夠通過(guò)某種方法查找到的,就不需要記憶.
那么,上面那么多數(shù)據(jù)類(lèi)型及其各種方法,都不需要記憶了,因?yàn)樗鼈兌伎梢酝ㄟ^(guò)下述方法但不限于這些方法查到(這句話(huà)的邏輯還是比較嚴(yán)密的,包括但不限于...)
在已經(jīng)學(xué)過(guò)的數(shù)據(jù)類(lèi)型中:
現(xiàn)在要介紹另外一種類(lèi)型的數(shù)據(jù),英文是set,翻譯過(guò)來(lái)叫做“集合”。它的特點(diǎn)是:有的可變,有的不可變;元素?zé)o次序,不可重復(fù)。
tuple算是list和str的雜合(雜交的都有自己的優(yōu)勢(shì),上一節(jié)的末后已經(jīng)顯示了),那么set則可以堪稱(chēng)是list和dict的雜合.
set擁有類(lèi)似dict的特點(diǎn):可以用{}花括號(hào)來(lái)定義;其中的元素沒(méi)有序列,也就是是非序列類(lèi)型的數(shù)據(jù);而且,set中的元素不可重復(fù),這就類(lèi)似dict的鍵.
set也有一點(diǎn)list的特點(diǎn):有一種集合可以原處修改.
下面通過(guò)實(shí)驗(yàn),進(jìn)一步理解創(chuàng)建set的方法:
>>> s1 = set("qiwsir")
>>> s1
set(['q', 'i', 's', 'r', 'w'])
把str中的字符拆解開(kāi),形成set.特別注意觀(guān)察:qiwsir中有兩個(gè)i,但是在s1中,只有一個(gè)i,也就是集合中元素不能重復(fù)。
>>> s2 = set([123,"google","face","book","facebook","book"])
>>> s2
set(['facebook', 123, 'google', 'book', 'face'])
在創(chuàng)建集合的時(shí)候,如果發(fā)現(xiàn)了重復(fù)的元素,就會(huì)過(guò)濾一下,剩下不重復(fù)的。而且,從s2的創(chuàng)建可以看出,查看結(jié)果是顯示的元素順序排列與開(kāi)始建立是不同,完全是隨意顯示的,這說(shuō)明集合中的元素沒(méi)有序列。
>>> s3 = {"facebook",123} #通過(guò){}直接創(chuàng)建
>>> s3
set([123, 'facebook'])
除了用set()
來(lái)創(chuàng)建集合。還可以使用{}
的方式,但是這種方式不提倡使用,因?yàn)樵谀承┣闆r下,python搞不清楚是字典還是集合。看看下面的探討就發(fā)現(xiàn)問(wèn)題了。
>>> 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'
從上述實(shí)驗(yàn)中,可以看出,通過(guò){}無(wú)法創(chuàng)建含有l(wèi)ist/dict元素的set.
認(rèn)真閱讀報(bào)錯(cuò)信息,有這樣的詞匯:“unhashable”,在理解這個(gè)詞之前,先看它的反義詞“hashable”,很多時(shí)候翻譯為“可哈?!保鋵?shí)它有一個(gè)不是音譯的名詞“散列”,這個(gè)在《字典(1)》中有說(shuō)明。網(wǎng)上搜一下,有不少文章對(duì)這個(gè)進(jìn)行詮釋。如果我們簡(jiǎn)單點(diǎn)理解,某數(shù)據(jù)“不可哈?!?unhashable)就是其可變,如list/dict,都能原地修改,就是unhashable。否則,不可變的,類(lèi)似str那樣不能原地修改,就是hashable(可哈希)的。
對(duì)于前面已經(jīng)提到的字典,其鍵必須是hashable數(shù)據(jù),即不可變的。
現(xiàn)在遇到的集合,其元素也要是“可哈?!钡?。上面例子中,試圖將字典、列表作為元素的元素,就報(bào)錯(cuò)了。而且報(bào)錯(cuò)信息中明確告知list/dict是不可哈希類(lèi)型,言外之意,里面的元素都應(yīng)該是可哈希類(lèi)型。
繼續(xù)探索一個(gè)情況:
>>> 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
這里報(bào)錯(cuò),進(jìn)一步說(shuō)明集合沒(méi)有序列,不能用索引方式對(duì)其進(jìn)行修改。
>>> 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']
分別用list()
和set()
能夠?qū)崿F(xiàn)兩種數(shù)據(jù)類(lèi)型之間的轉(zhuǎn)化。
特別說(shuō)明,利用set()
建立起來(lái)的集合是可變集合,可變集合都是unhashable類(lèi)型的。
還是用前面已經(jīng)介紹過(guò)多次的自學(xué)方法,把set的有關(guān)內(nèi)置函數(shù)找出來(lái),看看都可以對(duì)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']
為了看的清楚,我把雙劃線(xiàn)__開(kāi)始的先刪除掉(后面我們會(huì)有專(zhuān)題講述這些):
'add', 'clear', 'copy', 'difference', 'difference_update', 'discard', 'intersection', 'intersection_update', 'isdisjoint', 'issubset', 'issuperset', 'pop', 'remove', 'symmetric_difference', 'symmetric_difference_update', 'union', 'update'
然后用help()可以找到每個(gè)函數(shù)的具體使用方法,下面列幾個(gè)例子:
>>> help(set.add)
Help on method_descriptor:
add(...)
Add an element to a set.
This has no effect if the element is already present.
下面在交互模式這個(gè)最好的實(shí)驗(yàn)室里面做實(shí)驗(yàn):
>>> a_set = {} #我想當(dāng)然地認(rèn)為這樣也可以建立一個(gè)set
>>> a_set.add("qiwsir") #報(bào)錯(cuò).看看錯(cuò)誤信息,居然告訴我dict沒(méi)有add.我分明建立的是set呀.
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'dict' object has no attribute 'add'
>>> type(a_set) #type之后發(fā)現(xiàn),計(jì)算機(jī)認(rèn)為我建立的是一個(gè)dict
<type 'dict'>
特別說(shuō)明一下,{}這個(gè)東西,在dict和set中都用.但是,如上面的方法建立的是dict,不是set.這是python規(guī)定的.要建立set,只能用前面介紹的方法了.
>>> a_set = {'a','i'} #這回就是set了吧
>>> type(a_set)
<type 'set'> #果然
>>> a_set.add("qiwsir") #增加一個(gè)元素
>>> a_set #原處修改,即原來(lái)的a_set引用對(duì)象已經(jīng)改變
set(['i', 'a', 'qiwsir'])
>>> b_set = set("python")
>>> type(b_set)
<type 'set'>
>>> b_set
set(['h', 'o', 'n', 'p', 't', 'y'])
>>> b_set.add("qiwsir")
>>> b_set
set(['h', 'o', 'n', 'p', 't', 'qiwsir', 'y'])
>>> b_set.add([1,2,3]) #報(bào)錯(cuò).list是不可哈希的,集合中的元素應(yīng)該是hashable類(lèi)型。
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', 'qiwsir', 'y'])
除了上面的增加元素方法之外,還能夠從另外一個(gè)set中合并過(guò)來(lái)元素,方法是set.update(s2)
>>> help(set.update)
update(...)
Update a set with the union of itself and others.
>>> s1
set(['a', 'b'])
>>> s2
set(['github', 'qiwsir'])
>>> s1.update(s2) #把s2的元素并入到s1中.
>>> s1 #s1的引用對(duì)象修改
set(['a', 'qiwsir', 'b', 'github'])
>>> s2 #s2的未變
set(['github', 'qiwsir'])
>>> 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', 'qiwsir', 'y'])
>>> b_set.pop() #從set中任意選一個(gè)刪除,并返回該值
'[1,2,3]'
>>> b_set.pop()
'h'
>>> b_set.pop()
'o'
>>> b_set
set(['n', 'p', 't', 'qiwsir', 'y'])
>>> b_set.pop("n") #如果要指定刪除某個(gè)元素,報(bào)錯(cuò)了.
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: pop() takes no arguments (1 given)
set.pop()是從set中任意選一個(gè)元素,刪除并將這個(gè)值返回.但是,不能指定刪除某個(gè)元素.報(bào)錯(cuò)信息中就告訴我們了,pop()不能有參數(shù).此外,如果set是空的了,也報(bào)錯(cuò).這條是幫助信息告訴我們的,看官可以試試.
要?jiǎng)h除指定的元素,怎么辦?
>>> 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中的元素,否則就報(bào)錯(cuò).試一試:
>>> a_set
set(['i', 'a', 'qiwsir'])
>>> a_set.remove("i")
>>> a_set
set(['a', 'qiwsir'])
>>> a_set.remove("w")
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
KeyError: 'w'
跟remove(obj)類(lèi)似的還有一個(gè)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)
的信息對(duì)比,看看有什么不同.discard(obj)中的obj如果是set中的元素,就刪除,如果不是,就什么也不做,do nothing.新聞就要對(duì)比著看才有意思呢.這里也一樣.
>>> a_set.discard('a')
>>> a_set
set(['qiwsir'])
>>> a_set.discard('b')
>>>
在刪除上還有一個(gè)絕殺,就是set.clear(),它的功能是:Remove all elements from this set.(看官自己在交互模式下help(set.clear))
>>> a_set
set(['qiwsir'])
>>> a_set.clear()
>>> a_set
set([])
>>> bool(a_set) #空了,bool一下返回False.
False
集合,也是一個(gè)數(shù)學(xué)概念(以下定義來(lái)自維基百科)
集合(或簡(jiǎn)稱(chēng)集)是基本的數(shù)學(xué)概念,它是集合論的研究對(duì)象。最簡(jiǎn)單的說(shuō)法,即是在最原始的集合論─樸素集合論─中的定義,集合就是“一堆東西”。集合里的“東西”,叫作元素。若然 x 是集合 A 的元素,記作 x ∈ A。
集合是現(xiàn)代數(shù)學(xué)中一個(gè)重要的基本概念。集合論的基本理論直到十九世紀(jì)末才被創(chuàng)立,現(xiàn)在已經(jīng)是數(shù)學(xué)教育中一個(gè)普遍存在的部分,在小學(xué)時(shí)就開(kāi)始學(xué)習(xí)了。這里對(duì)被數(shù)學(xué)家們稱(chēng)為“直觀(guān)的”或“樸素的”集合論進(jìn)行一個(gè)簡(jiǎn)短而基本的介紹;更詳細(xì)的分析可見(jiàn)樸素集合論。對(duì)集合進(jìn)行嚴(yán)格的公理推導(dǎo)可見(jiàn)公理化集合論。
在計(jì)算機(jī)中,集合是什么呢?同樣來(lái)自維基百科,這么說(shuō)的:
在計(jì)算機(jī)科學(xué)中,集合是一組可變數(shù)量的數(shù)據(jù)項(xiàng)(也可能是0個(gè))的組合,這些數(shù)據(jù)項(xiàng)可能共享某些特征,需要以某種操作方式一起進(jìn)行操作。一般來(lái)講,這些數(shù)據(jù)項(xiàng)的類(lèi)型是相同的,或基類(lèi)相同(若使用的語(yǔ)言支持繼承)。列表(或數(shù)組)通常不被認(rèn)為是集合,因?yàn)槠浯笮」潭?,但事?shí)上它常常在實(shí)現(xiàn)中作為某些形式的集合使用。
集合的種類(lèi)包括列表,集,多重集,樹(shù)和圖。枚舉類(lèi)型可以是列表或集。
不管是否明白,貌似很厲害呀.
是的,所以本講僅僅是對(duì)集合有一個(gè)入門(mén).關(guān)于集合的更多操作如運(yùn)算/比較等,還沒(méi)有涉及呢.
更多建議: