Python學習之字典的基本操作及字典中的函數

在上一篇Python學習之字典當中,學習了Python一種獨特的數據對象類型,字典以及如何創建字典和創建字典的方法。
這一篇主要學習字典的基本操作及字典中的函數。對於字典的基本操作。

獲取字典的長度
使用內置函數len(dict)

>>> test = {"a":"1","b":"3","c":"4"}
>>> test
{'a': '1', 'c': '4', 'b': '3'}
>>> len(test)
3

通過鍵來查找字典中的值

>>> print test
{'a': '1', 'c': '4', 'b': '3', 'd': '5'}
>>> test['d']
'5'
>>> test['3']     #如果字典中不存在鍵,那麼就會報錯

Traceback (most recent call last):
  File "<pyshell#10>", line 1, in <module>
    test['3']
KeyError: '3'
>>> test['a']
'1'
>>> 

向字典中增加鍵值對

>>> print test
{'a': '1', 'c': '4', 'b': '3', 'd': '5'}
>>> test["e"] = "6"
>>> test
{'a': '1', 'c': '4', 'b': '3', 'e': '6', 'd': '5'}
>>> 

從字典中刪除一個鍵值對

>>> print test
{'a': '1', 'c': '4', 'b': '3', 'e': '6', 'd': '5'}
>>> del test['a']
>>> print test
{'c': '4', 'b': '3', 'e': '6', 'd': '5'}
>>> 

判斷某個鍵是否存在於字典中
關鍵代碼 key in dict,如果存在則返回true,如果不存在,則返回false

>>> print test
{'c': '4', 'b': '3', 'e': '6', 'd': '5'}
>>> 'c' in test
True
>>> 'a' in test
False
>>> 'f' in test
False
>>> 

字典中字符串的格式化輸出

>>> print test
{'website': 'https://www.baidu.com', 'name': 'baidu'}
>>> print "the web\'s name is %(name)s ,the web\'s website is %(website)s."%test
the web's name is baidu ,the web's website is https://www.baidu.com.
>>> 

從以上代碼中,我們可以看到,字符串中如果調用字典中的key,使用%( )s,然後在結尾使用% dict從字典中檢索key。
不過字典中的字符串的格式化輸出不怎麼實用。
下面我們寫一個網頁代碼來小試牛刀一下

>>> code = "<html><head><title>%(string)s</title><body><p>This is the %(page)s</p></body></head></html>"
>>> testdict = {"string":"test page","page":"test page"}
>>>> code % testdict
'<html><head><title>test page</title><body><p>This is the test page</p></body></head></html>'
>>> 

其實這個例子並沒有什麼實際意義,但是很好玩兒呀!

接着上面的,從這裏開始,開始學習字典中的函數
和前面所講述的其他對象一樣,字典中也有一些函數,通過這些函數,可以實現對字典的操作。

1、copy和deepcopy
通常,copy就是簡單的理解爲將原來的東西複製一份,但是如果以爲copy的含義僅僅是這個,那麼孩子,涉世未深,還得探索呀。在Python中,或者說其他的編程語言中,copy可不僅僅是那麼簡單的。

>>> a = 1
>>> b = a
>>> b
1

上面的代碼中,我們可以看到,我們似乎是得到了兩個1,但是真的是這樣嗎?我們知道,在Python中,對象有類型,變量無類型。所以,我們可以看得出,變量只是一個標籤而已,相當於爸爸有1塊錢,然後爸爸把1塊錢給了孩子,那麼孩子得到的依然使這1塊錢,1塊錢的實質是不變得。粗糙理解一下啊。我也是新手,不知道例子舉得恰不恰當。不信,我們可以通過id( )來驗證。

>>> a = 1
>>> b = a
>>> b
1
>>> id(a)
10728248
>>> id(b)
10728248
>>> 

在其它的數據類型中,也是同樣,這裏只實驗一下字典類型

>>> test
{'website': 'https://www.baidu.com', 'name': 'baidu'}
>>> demo = test
>>> demo
{'website': 'https://www.baidu.com', 'name': 'baidu'}
>>> id(test)
11179680
>>> id(demo)
11179680
>>> 

我們可以看到又是一個對象貼了兩個標籤,這是用賦值的方式實現對象的所謂的“假裝拷貝”。那麼如果是copy的方法呢

>>> test
{'website': 'https://www.baidu.com', 'name': 'baidu'}
>>> demo = test.copy()
>>> demo
{'website': 'https://www.baidu.com', 'name': 'baidu'}
>>> id(test)
11179680
>>> id(demo)
11349728
>>> 

我們發現,這次得到的demo和原來的demo是不同的,它在內存中另開闢了一個空間。如果我嘗試修改demo,那麼對於原來的test應該不會造成影響,實驗的結果會不會是如我所說的呢?

>>> test
{'website': 'https://www.baidu.com', 'name': 'baidu'}
>>> demo = test.copy()
>>> demo
{'website': 'https://www.baidu.com', 'name': 'baidu'}
>>> id(test)
11179680
>>> id(demo)
11349728
>>> demo ["name1"] = "google"
>>> demo
{'website': 'https://www.baidu.com', 'name': 'baidu', 'name1': 'google'}
>>> test
{'website': 'https://www.baidu.com', 'name': 'baidu'}
>>> 

如果不用copy,直接用賦值的方式改變結果呢?

>>> test
{'website': 'https://www.baidu.com', 'name': 'baidu'}
>>> demo = test
>>> demo
{'website': 'https://www.baidu.com', 'name': 'baidu'}
>>> demo ["name1"] = "google"
>>> demo
{'website': 'https://www.baidu.com', 'name': 'baidu', 'name1': 'google'}
>>> test
{'website': 'https://www.baidu.com', 'name': 'baidu', 'name1': 'google'}
>>> id(test)
11179680
>>> id(demo)
11179680
>>> 

我們發現如果修改了demo對象的值,那麼test對象的值也跟着改變了
前方高能預警,然而事情並非想象的那麼簡單,爲甚呢?我也不解,慢慢來看吧!

>>> test = {"name":"website","web":["baidu","google","360"]}
>>> test
{'web': ['baidu', 'google', '360'], 'name': 'website'}
>>> demo = test.copy()
>>> demo
{'web': ['baidu', 'google', '360'], 'name': 'website'}
>>> id(test)
11349728
>>> id(demo)
11351568
>>> 

通過實驗發現,testdemo在內存中是兩個不同的對象

>>> demo['web'].remove('360')
>>> demo
{'web': ['baidu', 'google'], 'name': 'website'}
>>> test
{'web': ['baidu', 'google'], 'name': 'website'}
>>> 

上面的代碼中,我們嘗試將字典中的web對應的列表中的360移除,按照我們之前的推測,demo和test在內存中是屬於兩個不同的對象,但是,我們發現,當我們移除demo中的360後,test中web對應的列表也跟着變化了。是不是開始暈圈圈了呢。
解釋:在demo所對應字典的對象中,鍵‘web’對應的值是一個列表,爲[‘baidu’, ‘google’, ‘360’],當用remove移除列表中的一個元素360後,變爲[‘baidu’, ‘google’]
毋庸置疑,前面所說的原理是有效的,但是爲什麼當值是列表的時候就不奏效了呢?
爲了解決這個迷惑,我們還得用id( )來破解,我爲什麼要說破解呢,我又不是一個hacker。

>>> test
{'web': ['baidu', 'google', '360'], 'name': 'website'}
>>> demo = test.copy()
>>> demo
{'web': ['baidu', 'google', '360'], 'name': 'website'}
>>> id(test)
11349728
>>> id(demo)
11351568
>>> demo['web'].remove('360')
>>> demo
{'web': ['baidu', 'google'], 'name': 'website'}
>>> test
{'web': ['baidu', 'google'], 'name': 'website'}
>>> id(demo)
11351568
>>> id(test)
11349728
>>> 

testdemo對應着兩個不同的對象,確實這樣,但是這個對象(字典)是由兩個鍵值對組成的,其中一個鍵的值是列表。

>>> test = {"name":"website","web":["baidu","google","360"]}
>>> demo = test.copy()
>>> id(test['web'])
140262388822528
>>> id(demo['web'])
140262388822528
>>> 

注意:我們發現了這樣一個事實,列表是同一個對象,但是,作爲字符串爲值得鍵值對應的是分屬不同的對象。

>>> test = {"name":"website","web":["baidu","google","360"]}
>>> demo = test.copy()
>>> id(test["web"])
140262388728536
>>> id(demo["web"])
140262388728536
>>> id(test["name"])
140262388812848
>>> id(demo["name"])
140262388812848
>>> demo['web'].remove('360')
>>> demo
{'web': ['baidu', 'google'], 'name': 'website'}
>>> test
{'web': ['baidu', 'google'], 'name': 'website'}
>>> id(test['name'])
140262388812848
>>> id(demo['name'])
140262388812848
>>> demo['name']="website1"       #改變name的值,下面的id就看到了
>>> demo
{'web': ['baidu', 'google'], 'name': 'website1'}
>>> test
{'web': ['baidu', 'google'], 'name': 'website'}
>>> id(test['web'])
140262388728536
>>> id(demo['web'])
140262388728536
>>> id(demo['name'])
140262388826688
>>> id(test['name'])
140262388812848
>>> 

這個事實說明了爲什麼修改一個列表,另外一個列表也跟隨的原因了;而修改一個字符串,另外一個字符串不跟隨着修改的原因了。
那麼問題來了,我們想要在改被複制中的字典中,修改字典中的key所對應的value的值,怎麼辦?
所以copy我們稱爲淺拷貝
所謂淺拷貝意思就是,Pyhon中的存儲的對象類型爲基本數據類型和,複雜數據類型,如果是基本數據類型,比如是int,str等,那麼在被複制的字典中,就會重新存儲,但是,如果是複雜的列表的對象類型,那麼Python使用copy就對被複制對象的數據進行引用。所以如果對象太複雜了,那麼還是別費勁了,引用一下就可以了。
所以Python引入了深拷貝deep copy,但是,要通過import copy導入一個模塊

>>> import copy
>>> test
{'web': ['baidu', 'google', '360'], 'name': 'website'}
>>> demo = copy.deepcopy(test)
>>> demo
{'web': ['baidu', 'google', '360'], 'name': 'website'}
>>> id(test["name"])
140262388812848
>>> id(demo["name"])
140262388812848
>>> id(test['web'])
140262388822600
>>> id(demo['web'])
140262388822888
>>> 

發現,對於列表不再是簡單的引用了。

>>> import copy
>>> test
{'web': ['baidu', 'google', '360'], 'name': 'website'}
>>> demo = copy.deepcopy(test)
>>> demo
{'web': ['baidu', 'google', '360'], 'name': 'website'}
>>> id(test["name"])
140262388812848
>>> id(demo["name"])
140262388812848
>>> id(test['web'])
140262388822600
>>> id(demo['web'])
140262388822888
>>> demo['web'].remove('360')
>>> demo
{'web': ['baidu', 'google'], 'name': 'website'}
>>> test
{'web': ['baidu', 'google', '360'], 'name': 'website'}
>>> 

果然不再跟隨着改變了,哈哈,試一試才過癮
試一下append(),大聲的告訴我,你已經忘了。

>>> demo['web'].append('sina')
>>> demo
{'web': ['baidu', 'google', 'sina'], 'name': 'website'}
>>> test
{'web': ['baidu', 'google', '360'], 'name': 'website'}
>>> 

使用clear

>>>help(dict.clear)
help on method_descriptor:

clear(...)
    D.clear() -> None.  Remove all items from D.
(END) 

dict.clear()意思是指將字典中的所有元素都清空。使字典成爲一個空字典
而之前我們接觸過del dict這個是指將字典從內存中刪除,不存在了。
上代碼,我也不喜歡婆婆媽媽,長篇大論

>>> a = {'a':1,'b':2}
>>> a
{'a': 1, 'b': 2}
>>> a.clear()
>>> a
{}
>>> b = {'a':1,'b':2}
>>> del b
>>> b
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'b' is not defined
>>> 

函數之get和setdefault
get()和之前的dict[ ]是由區別的,
get()中如果指定的Key不存在,則返回None,但是dict[ ]就會報錯
上代碼

>>> test
{'web': ['baidu', 'google', '360'], 'name': 'website'}
>>> print test.get('web')
['baidu', 'google', '360']
>>> print test.get('haha')     #返回None
None
>>> test['web']
['baidu', 'google', '360']
>>> test['haha']              #報錯
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
KeyError: 'haha'
>>> 

注意,但是get還有一種用法,我們使用幫助

>>>help(dict.get)
>get(...)
    D.get(k[,d]) -> D[k] if k in D, else d.  d defaults to None.
(END) 

意思就是如果鍵對應的值不存在則返回可選參數d,默認爲None

>>> print test.get('haha','python')
python
>>> 

setdefault( )函數

help(dict.setdefault)
Help on method_descriptor:

setdefault(…)
D.setdefault(k[,d]) -> D.get(k,d), also set D[k]=d if k not in D
(END)
解釋:如果key存在,則返回value,如果不存在,則返回None,並將其添加到字典中,如果不存在,在後面指定可選參數,則將不存在的Key和value添加到字典中。
以下代碼中可以解釋這一含義。

>>> test
{'web': ['baidu', 'google', '360'], 'name': 'website'}
>>> print test.setdefault('web')
['baidu', 'google', '360']
>>> print test.setdefault('haha')
None
>>> print test
{'web': ['baidu', 'google', '360'], 'haha': None, 'name': 'website'}
>>> print test.setdefault('code','python')
python
>>> print test
{'web': ['baidu', 'google', '360'], 'code': 'python', 'haha': None, 'name': 'website'}
>>> 

除了以上字典中的函數,在字典中,還有’
items/iteritems,keys/iterkeys,values/itervalues函數
這三組函數有相似的地方,所以在這裏只實驗第一種函數,相信另外兩種函數只要同學們一看就會懂。

help(dict.items)
Help on method_descriptor:

items(…)
D.items() -> list of D’s (key, value) pairs, as 2-tuples
(END)
解釋,列出字典中的鍵值對,列表中的元素是由Keyvalue組成的一個元組
代碼:

>>> test
{'web': ['baidu', 'google', '360'], 'code': 'python', 'haha': None, 'name': 'website'}
>>> test.items()
[('web', ['baidu', 'google', '360']), ('code', 'python'), ('haha', None), ('name', 'website')]
>>> 

itertems( )函數

help(dict.iteritems)
Help on method_descriptor:

iteritems(…)
D.iteritems() -> an iterator over the (key, value) items of D
(END)
先看代碼

>>> test
{'web': ['baidu', 'google', '360'], 'code': 'python', 'haha': None, 'name': 'website'}
>>> test.iteritems()
<dictionary-itemiterator object at 0x7f9161dcff70>
>>> type(test.iteritems())
<type 'dictionary-itemiterator'>
>>> list(test.iteritems())
[('web', ['baidu', 'google', '360']), ('code', 'python'), ('haha', None), ('name', 'website')]
>>> 

我們可以看到,如果直接使用dict.iteritems( ),那麼我們將會得到一個dictionary-itemiterator類型,不過這種迭代器類型的數據不能直接輸出,必須要使用List( )轉換才能輸出。
另外的兩種函數也同這個類似。
pop和popitem函數
不知道你是否記得在學習列表的時候,刪除列表中的元素的函數是哪一個嗎?悄悄告訴我,你是不是忘了。哈哈
沒錯,就是pop和remove,這兩個的區別在於
list.remove(x)用來刪除指定的元素,而list.pop([x])用於刪除指定索引的元素,如果不提供索引值,就會默認刪除最後一個

help(dict.pop)
Help on method_descriptor:

pop(…)
D.pop(k[,d]) -> v, remove specified key and return the corresponding value.
If key is not found, d is returned if given, otherwise KeyError is raised
(END)
解釋:刪除指定鍵的鍵值對,如果Key沒有被發現,則返回可選給定的可選參數,否則,則會引發KeyError錯誤。
還是看代碼吧:

>>> test
{'web': ['baidu', 'google', '360'], 'code': 'python', 'haha': None, 'name': 'website'}
>>> test.pop('code')
'python'
>>> test
{'web': ['baidu', 'google', '360'], 'haha': None, 'name': 'website'}
>>> test.pop('code')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
KeyError: 'code'
>>> test.pop('code','python')
'python'
>>> test
{'web': ['baidu', 'google', '360'], 'haha': None, 'name': 'website'}
>>> 

popitem( )函數和List.pop()相似,可以不用寫參數,但是注意,popitem()是隨機刪除,而list.pop()是刪除最後一個
代碼呈上:

>>> test
{'web': ['baidu', 'google', '360'], 'haha': None, 'name': 'website'}
>>> demo.popitem()
('web', ['baidu', 'google', 'sina'])
>>> demo.popitem()
('name', 'website')
>>> 

注意,如果字典中沒有值得話,當使用popitem的時候,就會提示字典已經爲空了,沒有可以要刪除的東西了。
update函數
顧名思義,更新字典中的值

help(dict.update)
Help on method_descriptor:

update(…)
D.update(E, **F) -> None. Update D from dict/iterable E and F.
If E has a .keys() method, does: for k in E: D[k] = E[k]
If E lacks .keys() method, does: for (k, v) in E: D[k] = v
In either case, this is followed by: for k in F: D[k] = F[k]
(END)

>>> up = {"test":"this is test"}
>>> down = {"yes":"you are right"}
>>> up.update(down)
>>> up
{'test': 'this is test', 'yes': 'you are right'}
>>> down.update([("code","python"),("code1","java")])
>>> down
{'code1': 'java', 'yes': 'you are right', 'code': 'python'}
>>> 

hash_key函數

help(dict.has_key)
Help on method_descriptor:

has_key(…)
D.has_key(k) -> True if D has a key k, else False
(END)

解釋:這個函數的功能是判斷字典中是否存在某個鍵
如果存在,則返回true,否則返回false
本節學習的最後一個函數了,以代碼的方式結束

>>> test
{'web': ['baidu', 'google', '360'], 'haha': None, 'name': 'website'}
>>> test.has_key('web')
True
>>> test.has_key('code')
False
>>> 

好了,以上就是對於字典的基本操作和字典中的函數的操作,都是常見的操作和函數。當然,字典中的函數不僅僅是這些,慢慢來,以後還多的是呢。
明天更新集合。
晚安!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章