Python第五課(字典)
字典
序列這種數據結構是通過序號來訪問調用元素集合中的值。但日常生活中的有些對象,兩個對象之間存在某種關聯關系。比如說電話號碼屬於某個人,電話號碼和人之間就有屬於的關系,想根據人的姓名來查找出電話號碼,使用序列就不是特別的方便。這種情況下如果能夠使用人的名字來進行查詢就方便的多了,字典就是一種通過名字來訪問調用值的數據結構。字典是python的一種映射類型。字典中的值沒有特殊的順序。
- 創建和使用字典
字典由鍵值對組成,使用大括號括起來。鍵值對使用“鍵:值”的格式作為一個整體被包含在大括號中。
創建一個字典:name={‘lufei’:00000,‘suolong’:00001}
調用字典中中的鍵值:name[‘lufei’]
- dict函數
和list函數、tuple函數相似,dict函數可以通過其他字典(映射)或者(鍵,值)對的序列建立字典。也可以通過關鍵字來建立字典。
1 >>> name=[(‘lufei‘,0),(‘suolong‘,1)] 2 >>> a=dict(name) #通過包含鍵值對的序列建立字典 3 >>> a 4 {‘lufei‘: 0, ‘suolong‘: 1} 5 >>> b=dict(name=‘lufei‘,agg=19) #通過關鍵字建立字典 6 >>> b 7 {‘name‘: ‘lufei‘, ‘agg‘: 19}
- 字典的基本操作
1.len(d)返回字典d中鍵值對的數量
2.d[k]返回字典d中關聯到鍵d的值
3.d[k]=v將值v關聯到鍵k上
4.del d[k]刪除鍵位k的鍵值對
5.k in d成員資格函數,判斷字典d中是否含有鍵k
- 字典於序列的區別
1.序列中值對應的是序號,再序列中不能給不存在的序號賦值;字典中值對應的是鍵,字典中可以給不存在的鍵賦值,賦值後字典自動創建新的鍵值項;
2.成員資格,序列使用成員資格函數判斷的是某個值是否存在於序列中;字典使用成員資格函數判斷的是某個鍵是否存在於字典中。
- 字典的格式化字符串
在學習字符串時學習了如何用格式化字符串對元組進行格式化,同樣使用格式化字符串也可以對字典的值進行格式化處理
在格式化操作符(%)後面跟字典的鍵並使用小括號括起來,後面再正常使用其他說明元素。結果會使用字典中鍵關聯的值替換這部分內容。使用字典不需要特意的去註意值得順序,在這點上來說是比使用元組更加方便的。
- 字典方法
1.clear
清除字典中所有的項,clear方法在原位置操作,且不返回任何值
1 >>> a={‘lufei‘:0,‘suolong‘:1} 2 >>> b=a #將字典的內存地址賦值給b 3 >>> name=a.clear() #字典a調用clear方法,並將結果返回的值賦值給變量name 4 >>> b #字典b所有項也被清除了,說明a的clear是在內存原位置進行的清除操作 5 {} 6 >>> name 7 >>> print(name) #打印name的值為None說明方法clear不返回任何值 8 None
1 >>> a={‘lufei‘:0,‘suolong‘:1} 2 >>> b=a 3 >>> a={} #這裏是這段代碼與上面一段代碼唯一不同的。說明賦值語句是在內存中重新分配一片空間創建一個空字典並賦值給了變量a,而原來內存中的那個字典並沒有被刪除 4 >>> b 5 {‘lufei‘: 0, ‘suolong‘: 1}
2.copy
copy方法返回一個具有相同鍵值對的新字典。
1 >>> a={‘lufei‘:‘cap‘,‘haizei‘:[‘suolong‘,‘namei‘,‘qiaoba‘]} 2 >>> b=a.copy() #字典a調用copy方法,並將返回的值賦值給b 3 >>> b 4 {‘lufei‘: ‘cap‘, ‘haizei‘: [‘suolong‘, ‘namei‘, ‘qiaoba‘]} #看到結果字典b和a有一模一樣的鍵值對 5 >>> a[‘lufei‘]=‘haha‘ #修改字典a中鍵‘lufei’的值 6 >>> a[‘haizei‘].remove(‘namei‘) #修改字典a中鍵‘haizei’的值 7 >>> a 8 {‘lufei‘: ‘haha‘, ‘haizei‘: [‘suolong‘, ‘qiaoba‘]} #第一次修改僅a發生了變化,b還是copy後的值 9 >>> b 10 {‘lufei‘: ‘cap‘, ‘haizei‘: [‘suolong‘, ‘qiaoba‘]} #第二次修改字典b也發生了變化
為什麽會這樣?同樣是對原來的字典a做了操作,為什麽賦值操作在copy得到的b中沒有同步修改,對作為鍵值得列表的修改同步了?這是因為賦值操作和列表的部分方法在內存中的處理方法不同。賦值是重新開辟一塊地址空間存放新的值並把值賦給需要的變量,而不需要的變量還是指向原來的值。而剛才的列表的remove操作是在列表的原位置進行移除元素,也就是說兩個變量都是指向的位置a上的值,通過其中一個變量來對a的值進行了修改,兩個變量再去訪問位置a時,結果是一樣的。
有了弄清楚copy後賦值和修改這個過程在內存中的變化介紹一個函數id,id函數返回變量的值在內存中的地址
1 >>> a={‘lufei‘:‘cap‘,‘haizei‘:[‘suolong‘,‘namei‘,‘qiaoba‘]} #創建字典a 2 >>> b=a.copy() #copy字典a然後賦值給變量b 3 >>> id(a) 4 2197092086792 5 >>> id(b) 6 2197096782344 #分別查看字典a和字典b在內存中的地址,地址不相同說明copy操作是在內存中開辟一片空間,並創建了一個和字典a一模一樣的字典b 7 >>> id(a[‘haizei‘]) 8 2197096789128 9 >>> id(b[‘haizei‘]) 10 2197096789128 #查看字典a和字典b中的一個類型為列表的值在內存中的地址,地址相同說明了字典和字典b中的這個值指向內存中的同一個地址空間。如果這個列表改變那麽a和b將同時改變 11 >>> a[‘lufei‘]=‘haha‘ 12 >>> a 13 {‘haizei‘: [‘suolong‘, ‘namei‘, ‘qiaoba‘], ‘lufei‘: ‘haha‘} 14 >>> b 15 {‘haizei‘: [‘suolong‘, ‘namei‘, ‘qiaoba‘], ‘lufei‘: ‘cap‘} 16 >>> id(a) 17 2197092086792 18 >>> id(b) 19 2197096782344 20 >>> a[‘haizei‘].remove(‘namei‘) 21 >>> a 22 {‘haizei‘: [‘suolong‘, ‘qiaoba‘], ‘lufei‘: ‘haha‘} 23 >>> b 24 {‘haizei‘: [‘suolong‘, ‘qiaoba‘], ‘lufei‘: ‘cap‘} 25 >>> id(a) 26 2197092086792 27 >>> id(b) 28 2197096782344 29 >>> id(a[‘haizei‘]) 30 2197096789128 31 >>> id(b[‘haizei‘]) 32 2197096789128
在淺copy中,對值進行替換操作時,可以僅在副本字典上修改,而原字典不變;但是當鍵關聯的值是一個數據結構如列表,修改操作又是在原位置進行的操作時,在修改副本字典的同時原字典也會跟著被修改;然而在大多數情況下這種結果並不是我們想要的。我們用copy創建一個副本字典時,是想通過修改副本字典得到一個新的字典,同時還保存原始的字典。
要實現這樣的結果就要使用深copy——deepcopy。因為deepcopy是copy模塊中的一個函數,在使用的時候需要使用import語句從模塊中導入函數。
1 >>> from copy import deepcopy #從copy模塊中導入deepcopy函數 2 >>> name={‘captain‘:‘lufei‘,‘sailor‘:[‘suolong‘,‘namei‘,‘qiaoba‘]} 3 >>> deepcopy_name=deepcopy(name) #調用deepcopy函數創建字典name的副本deepcopy_name 4 >>> deepcopy_name 5 {‘sailor‘: [‘suolong‘, ‘namei‘, ‘qiaoba‘], ‘captain‘: ‘lufei‘} 6 >>> deepcopy_name[‘captain‘]=‘haha‘ #修改副本字典中的簡單值 7 >>> deepcopy_name[‘sailor‘].remove(‘namei‘) #修改副本字典中的列表中的值 8 >>> name 9 {‘sailor‘: [‘suolong‘, ‘namei‘, ‘qiaoba‘], ‘captain‘: ‘lufei‘} 10 >>> deepcopy_name 11 {‘sailor‘: [‘suolong‘, ‘qiaoba‘], ‘captain‘: ‘haha‘} #結果副本字典被修改,而原字典沒有被修改
3.fromkeys
通過給出的參數列表創建一個以參數列表中元素為鍵名稱,默認值(默認為None)為鍵值的字典
1 >>> {}.fromkeys((‘name‘,‘age‘)) 2 {‘name‘: None, ‘age‘: None}
上面的描述並不是特別準確,從代碼中可以看到。是先創建了一個空的字典,然後字典調用fromkeys方法,建立另外一個字典
1 >>> name={‘a‘:‘a‘,‘b‘:‘b‘} 2 >>> name.fromkeys((‘c‘,‘d‘)) 3 {‘c‘: None, ‘d‘: None} 4 >>> name 5 {‘b‘: ‘b‘, ‘a‘: ‘a‘}
fromkeys不是在原字典上添加參數中給出的鍵,而是使用參數中給出的鍵創建一個新的字典。
1 >>> name=dict.fromkeys((‘name‘,‘age‘)) 2 >>> name 3 {‘name‘: None, ‘age‘: None}
使用dict函數不給參數可以創建一個空字典,那麽dict函數本身就可以作為字典來調用fromkeys方法。
4.get
通過鍵名稱查詢字典中與鍵關聯的值,get方法特別的是如果參數中給出鍵名稱在字典中不存在,將返回一個默認值,這個值可以在參數中給出。
1 >>> name={‘name‘:‘lufei‘,‘age‘:‘19‘} 2 >>> name.get(‘name‘) 3 ‘lufei‘ 4 >>> a=name.get(‘job‘) 5 >>> print(a) 6 None 7 >>> name 8 {‘name‘: ‘lufei‘, ‘age‘: ‘19‘} 9 >>> b=name.get(‘job‘,‘meiyou‘) 10 >>> b 11 ‘meiyou‘
5.has_key
這個方法的效果和成員資格一樣,在3.0後python不包含這個方法,所以這裏不詳細說明使用方法是dict.has_key(k),含義為判斷字典dict中是否包含k鍵,若包含返回True,若不包含返回False。
6.keys and iterkeys
keys方法將字典中的鍵名稱以列表方式返回,而iterkeys方法將字典中的鍵名稱以叠代器方式返回。
1 >>> name 2 {‘name‘: ‘lufei‘, ‘age‘: ‘19‘} 3 >>> name.keys() 4 dict_keys([‘name‘, ‘age‘]) 5 >>> a=name.keys() 6 >>> a 7 dict_keys([‘name‘, ‘age‘])
這樣的返回值目前還不明白有什麽作用,iterkeys在明白叠代器時再做說明。
7.pop
在字典中pop方法通過給定鍵刪除鍵值對並返回鍵對應的值。
1 >>> a={‘x‘:1,‘y‘:2} 2 >>> a.pop(‘x‘) 3 1 4 >>> a 5 {‘y‘: 2}
8.popitem
在列表中pop方法用來刪除列表的最後一個元素並返回這個元素的值。因為字典是無序的,沒有“最後一個元素”,字典中popitem刪除的鍵值對是隨機的。
1 >>> name={‘a‘:‘a‘,‘b‘:‘b‘,‘c‘:‘c‘} 2 >>> name.popitem() 3 (‘c‘, ‘c‘) 4 >>> name.popitem() 5 (‘b‘, ‘b‘)
以上字典鍵值對數量較少,調用popitem方法的數量較少,給人一種刪除的鍵值對是目前在顯示的順序用最後的一對鍵值對的感覺。
9.setdefault
setdefault方法是加強版的get方法。get是通過給定的鍵查詢與鍵關聯的值,如果鍵不存在則返回一個默認值(可以在參數中給出默認是None)。而setdefault方法是通過給定的鍵查詢字典中鍵關聯的值,如果鍵值不存在返回默認的值(可在參數中設置),並在字典中添加這個鍵值對。
1 >>> name={‘captain‘:‘lufei‘,‘suolong‘:‘namei‘} 2 >>> name.setdefault(‘captain‘) 3 ‘lufei‘ 4 >>> print(name.setdefault(‘xiangji‘)) 5 None 6 >>> name 7 {‘suolong‘: ‘namei‘, ‘xiangji‘: None, ‘captain‘: ‘lufei‘} 8 >>> name.setdefault(‘luobin‘,‘haha‘) 9 ‘haha‘ 10 >>> name 11 {‘suolong‘: ‘namei‘, ‘xiangji‘: None, ‘captain‘: ‘lufei‘, ‘luobin‘: ‘haha‘}
上面代碼說明三點setdefault的用法:給出鍵,返回鍵關聯的值;如果查詢的鍵在字典中不存在則返回None值,並在字典中添加鍵值對;可以修改默認值None的值。
10.update
可以利用一個字典項更新另一個字典。鍵不存在則添加新鍵值對,如果存在相同的鍵則覆蓋鍵值對。
1 >>> name 2 {‘suolong‘: ‘namei‘, ‘xiangji‘: None, ‘captain‘: ‘lufei‘, ‘luobin‘: ‘haha‘} 3 >>> a={‘haijun‘:‘hehe‘} 4 >>> name.update(a) 5 >>> name 6 {‘suolong‘: ‘namei‘, ‘xiangji‘: None, ‘captain‘: ‘lufei‘, ‘luobin‘: ‘haha‘, ‘haijun‘: ‘hehe‘} 7 >>> a[‘haijun‘]=‘chacha‘ 8 >>> name.update(a) 9 >>> name 10 {‘suolong‘: ‘namei‘, ‘xiangji‘: None, ‘haijun‘: ‘chacha‘, ‘captain‘: ‘lufei‘, ‘luobin‘: ‘haha‘}
11.values and itervalues
values是以列表的形式返回字典中的值,itervalues是以叠代器的形式返回列表中的值
1 >>> name 2 {‘suolong‘: ‘namei‘, ‘xiangji‘: None, ‘haijun‘: ‘chacha‘, ‘captain‘: ‘lufei‘, ‘luobin‘: ‘haha‘} 3 >>> name.values() 4 dict_values([‘namei‘, None, ‘chacha‘, ‘lufei‘, ‘haha‘])
Python第五課(字典)