在Python中字典屬於一種映射類型,它和set相同,一樣屬於非線性結構存儲,Python官方對dict有以下解釋python
簡單來講:字典是由key:value鍵值對組成的數據的集合,它的主要特色是 可變的
、無序的
、不重複的
。linux
字典的key必須是可hash對象,之因此快,由於其本質上使用空間換了時間。centos
字典是除set集合之外另外一種可變的非線性容器模型,在Python中很是強大,適合各類結構數據的存儲、嵌套等。數據結構
字典的每一個key到value的鍵值對用冒號(:)分割,每對之間用逗號(,)分割,整個字典包括在花括號({})中。例:{'a':1, 'b':2}
,Python提供了多種建立字典的方式,以下:app
d = dict()
或者 d = {}
dict(**kwargs)
: 使用name=value對,來初始化一個字典dict(iterable, **kwargs)
:使用可迭代對象和name=value構造字典,注意可迭代對象必須是一個二元結構
dict(mapping, **kwargs)
: 使用一個字典構造另外一個字典dic = {'a':1, 'b':2, 'c':3, 'd':[1,2,3]}
dic = dict.fromkeys(iterable, value)
: 使用可迭代對象的值做爲key生成字典,value默認爲0,不然用指定的value對字典進行初始化。In [114]: d1=dict()
In [115]: d2={}
In [118]: d3 = dict(a=1,b=2)
In [120]: d3
Out[120]: {'a': 1, 'b': 2}
In [124]: d4 = dict([('a',1),('b',2)], c=3, d=4)
In [125]: d5 = dict(d4,e=5,f=6)
In [126]: d7 = dict.fromkeys(range(5))
In [127]: d8 = dict.fromkeys(range(5),100)
In [128]: d7
Out[128]: {0: None, 1: None, 2: None, 3: None, 4: None}
In [131]: d8
Out[131]: {0: 100, 1: 100, 2: 100, 3: 100, 4: 100}
複製代碼
有以下三種方式訪問字典的鍵值對:函數
d[key]
: 返回key對應的value,key不存在拋出KeyError異常dict.get(key[, default])
: 返回key對應的value,key不存在返回缺省值,若是沒有設置缺省值趕回Nonedict.setdefault(key[, default])
: 返回key對應的值value,key不存在,添加key:value鍵值對(value設置爲default),並返回value,若是default沒有設置缺省爲NoneIn [32]: dic = {'a':1, 'b':2, 'c':3, 'd':4}
In [33]: dic['a']
Out[33]: 1
In [34]: dic['e'] # 不存在'e'這個key,因此直接訪問會出現異常
---------------------------------------------------------------------------
KeyError Traceback (most recent call last)
<ipython-input-34-87d22c709971> in <module>
----> 1 dic['e']
KeyError: 'e'
In [35]: dic.get('a') # key存在,則返回對應的值
Out[35]: 1
In [36]: dic.get('e') # 不存在,默認會返回None,ipython優化了None的輸出,因此這裏無顯示
In [37]: dic.get('e','not exist') # 不存在時,由指定的default進行返回
Out[37]: 'not exist'
In [38]: dic.setdefault('a', 'ok?') # 設置a的值爲ok?,a存在,因此返回a對應的值1
Out[38]: 1
In [39]: dic.setdefault('e', 'ok?') # 設置e的值爲ok?,e不存在,因此設置並放回value(key不存在時等同於設置並訪問了)
Out[39]: 'ok?'
In [40]: dic
Out[40]: {'a': 1, 'b': 2, 'c': 3, 'd': 4, 'e': 'ok?'}
複製代碼
固然字典也能夠被迭代訪問,後面介紹優化
因爲字典可變、非線性、無序的特性,並且字典的key必須是可hash的對象,查找某個key也是直接hash(),而後找到對應的房間的,因此咱們對它某個key的修改能夠理解爲是O(1)
的操做,效率很高,主要有如下幾種方法。centos7
d[key] = value
: 將key對應的值修改成value,key不存在添加新的key:value對。dic.update([other]) --> None
: 使用另外一個字典的k,v對更新本字典,key不存在時添加,存在時則覆蓋,因此不會返回新的字典,屬於原地修改。dic.pop(key[, default])
: key存在,移除它,並返回它的value,key不存在返回指定的default,若是default未指定,那麼會返回KeyError異常。dic.popitem()
: 移除並返回一個任意的鍵值對,字典爲empty時,拋出KeyError異常。dic.clear()
: 清空字典。del dic['a']
: 通用的刪除變量方法。In [41]: dic
Out[41]: {'a': 1, 'b': 2, 'c': 3, 'd': 4, 'e': 'ok?'}
In [42]: dic['a'] = 1000
In [43]: dic
Out[43]: {'a': 1000, 'b': 2, 'c': 3, 'd': 4, 'e': 'ok?'}
In [44]: dic2 = {'a':200,'f':50}
In [45]: dic.update(dic2)
In [46]: dic
Out[46]: {'a': 200, 'b': 2, 'c': 3, 'd': 4, 'e': 'ok?', 'f': 50}
In [48]: dic.pop('a') # 彈出一個key'a',key存在返回key對應的value
Out[48]: 200
In [49]: dic.pop('g') # 彈出一個key'g',key不存在,又沒有指定default,則會報KeyError異常
---------------------------------------------------------------------------
KeyError Traceback (most recent call last)
<ipython-input-49-311c3ba80251> in <module>
----> 1 dic.pop('g')
KeyError: 'g'
In [50]: dic.pop('g','not exist') # 指定了default,當key不存在時,會返回指定的default值
Out[50]: 'not exist'
In [51]: dic.popitem() # 彈出一個key:valyue鍵值對,返回對象是元組形式
Out[51]: ('d', 4)
In [52]: dic
Out[52]: {'b': 2, 'c': 3, 'e': 'ok?', 'f': 50}
In [53]: del dic['e']
In [54]: dic
Out[54]: {'b': 2, 'c': 3, 'f': 50}
In [55]: dic.clear()
In [56]: dic
Out[56]: {}
複製代碼
當咱們以字典的某個對象好比keys,values,items等爲條件對字典進行遍歷時,咱們不能在遍歷的同時刪除字典的元素,字典在運行時不容許長度改變,可是在list中這種操做是能夠的,可是會獲得意想不到的結果,建議對容器進行遍歷的同時不要修改它的長度。spa
In [7]: s
Out[7]: {'a': 1, 'b': 2, 'c': 4, 'd': 5, 'e': 7, 'j': 10}
In [8]: len(s)
Out[8]: 6
In [10]: for i in range(6):
...: s.popitem()
...:
In [11]: s
Out[11]: {}
# 下面這種方式是錯的,也是以爲不能夠的。
for i in s.keys():
s.pop(i)
複製代碼
在Python中,咱們所說的基本數據結構:字符串、元組、列表,集合,包括字典,均可以認爲是一個容器箱子,只要是容器,咱們就能夠進行遍歷(是否有序和是否能夠遍歷沒有必然關係,只不過有序的話是順序拿出,而無序則是隨機拿出),咱們可使用多種方式對字典進行迭代遍歷,可是有些地方和其餘類型不一樣。code
dic.keys()
: --> dict_keys
--> 返回字典dic的全部key組成的一個dict_keys視圖集合(類set結構,不會生成新的內存空間
)。
In [64]: dic = {'a':1, 'b':2, 'c':3, 'd':4}
In [65]: for key in dic:
...: print(key)
a
d
c
b
In [66]: for key in dic.keys():
...: print(key)
a
d
c
b
In [67]: dic.keys()
Out[67]: dict_keys(['a', 'd', 'c', 'b'])
複製代碼
迭代字典就是在迭代字典的key,因此直接迭代字典和使用字典的keys()方法返回一個keys的視圖而後再迭代,是同樣的效果。
dic.values()
: --> dict_values
--> 返回字典dic的全部values組成的一個dict_values視圖集合(類set結構,不會生成新的內存空間
)。
In [69]: for i in dic:
...: print(dic[i])
1
4
3
2
In [70]: for i in dic.values():
...: print(i)
1
4
3
2
In [71]: dic.values()
Out[71]: dict_values([1, 4, 3, 2])
複製代碼
能夠首先遍歷字典的key,而後再經過key來訪問對應的value,也能夠經過values()直接訪問values。
dic.items()
: --> dict_items
--> 返回字典dic的全部的key和value(每一個key和value的鍵值對由元組表示)組成的一個dict_items視圖集合(類set結構,不會生成新的內存空間
)。
In [75]: for i in dic.items():
...: print(i)
...:
('a', 1)
('d', 4)
('c', 3)
('b', 2)
In [77]: for key,value in dic.items():
...: print('key:{} value:{}'.format(key,value))
...:
key:a value:1
key:d value:4
key:c value:3
key:b value:2
In [78]:
複製代碼
因爲返回的每一個鍵值對爲元組格式,那麼利用咱們前面學的封裝與結構,能夠很方便的獲取key和它對應的value
在Python3中,keys、values、items方法返回一個相似一個生成器的可迭代對象,不會把函數的返回結果複製到內存空間中。
[11:20:32 python@centos7 ~]$python
Python 2.7.5 (default, Oct 30 2018, 23:45:53)
[GCC 4.8.5 20150623 (Red Hat 4.8.5-36)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> s = {'a':1,'b':2}
>>> s.keys() # 直接生成一個keys的列表
['a', 'b']
>>> s.iterkeys() # 對象,迭代能夠獲取數據
<dictionary-keyiterator object at 0x7f271c5fa520>
>>>
複製代碼
defaultdit object是dict的子類,咱們稱它爲默認值字典,即在建立字典時給全部的value指定一個默認值,它存放在collections模塊中,使用前須要先進行導入。爲何有默認值字典這種類型呢?那麼請看以下代碼:
dic = {}
for i in 'abacdabeddfef':
if i not in dic: # 這句其實也能夠優化爲 dic[i] = dic.get(i, 0) + 1
dic[i] = 0
dic[i] += 1
print(dic)
複製代碼
咱們在計算一個字符串或者一個列表中的元素重複的次數時,一般會用到字典對齊進行計數,若是元素不存在字典中,那麼就須要初始化元素,當咱們使用默認值字典時,就能夠優化的更簡潔。
from collections import defaultdict
dic = defaultdict(int) # defaultdict(lambda :0) 這種方法也能夠設置默認爲0
for i in 'abacdabeddfef':
dic[i] += 1 # 默認是int型,能夠直接加減
print(dic)
複製代碼
Ordered dictionaries像一個有序字典,可是它記住的是插入元素的順序。當咱們迭代有序字典時,它會按照這些鍵值對插入的順序返回。它一樣存在於collections模塊中,須要使用是請首先導入。
In [1]: from collections import OrderedDict
In [2]: dic = OrderedDict()
In [5]: dic = dic.fromkeys('abc',1)
In [6]: dic
Out[6]: OrderedDict([('a', 1), ('b', 1), ('c', 1)])
In [8]: for k,v in dic.items(): # 按照插入的順序
...: print(k,v)
...:
a 1
b 1
c 1
In [10]: dic = dict([('a', 1), ('b', 1), ('c', 1)])
In [11]: for k,v in dic.items(): # 無序的
...: print(k,v)
...:
a 1
c 1
b 1
In [12]:
複製代碼
在3.6的版本的python在python/ipython解釋器中,直接迭代或者打印時,是有序的(OrderedDict),可是在3.5版本之前都是隨機的!