字典
字典是一種key-value結構
字典對象操作
新建字典
- 方式1:d = {}
- 方式2:d = dict()
- 方式3:d = {'a':1, 'b': 2}
- 方式4:d = dict([('a',1), ('b', 2)]) # 可迭代對象的元素必須是一個二元組, 二元組的第0個元素爲字典的key, 第一個元素爲字典的value。
- 方式5:傳入的可迭代元素爲key, 值爲None。
In [26]: dict.fromkeys(range(5)) # 傳入的可迭代元素爲key, 值爲None。
Out[26]: {0: None, 1: None, 2: None, 3: None, 4: None}
In [27]: d = dict.fromkeys(range(5), 'abc') # 傳入的可迭代對象的元素爲key, 值爲abc。
In [28]: d
Out[28]: {0: 'abc', 1: 'abc', 2: 'abc', 3: 'abc', 4: 'abc'}
- 方法6:接收一個字典,不常用
- 例如:In [33]: d = dict({'a':1, 'b':3}) # 接收一個字典
刪除字典
字典元素的操作
增加與修改
- 可以直接下標操作,如果key不存在則會增加kv對,如果key存在則會修改其value
- d.update([('c', 3), ('p', 0)]):傳入一個字典,該方法通常用於合併字典
In [30]: d['acc'] = 5 # 可以直接使用key做爲下標, 對某個不存在的下標賦值, 會增加kv對。
In [31]: d.update([('c', 3), ('p', 0)]) # update傳入參數和dict一樣
In [32]: d
Out[32]: {0: 'abc', 1: 'abc', 2: 'abc', 3: 'abc', 4: 'abc', 'acc': 5, 'c': 3, 'p': 0}
In [34]: d.update({'r': 2, 'd': 3}) # update通常用於合併字典
In [36]: d.update([('r', 2), ('d', 2)]) # 傳入一個值
In [37]: d['a'] = 2 # 當key存在, 對下標賦值的時候, 會修改這個key對應的value。
刪除
- d.pop(0):pop方法用於從字典刪除一個key, 並返回其value。當key不存在時會拋出KeyError
- d.pop(0, 'defalut'): 當刪除不存在的key, 並且指定了默認值時, 不會拋出KeyError, 並且返回默認值
- d.popitem():popitem隨機返回並刪除一個kv對的二元組,如果空字典則會拋出KeyError
- d.clear():clear方法清空一個字典
- del d['c']:不過通常用pop刪除key
In [4]: d.pop(0) # pop方法用於從字典刪除一個key, 並返回其value
Out[4]: 'abc'
In [5]: d.pop(0) # 當刪除不存在的key的時候, 會拋出KeyError
---------------------------------------------------------------------------
KeyError Traceback (most recent call last)
<ipython-input-5-e1702b259b84> in <module>()
----> 1 d.pop(0)
KeyError: 0
In [6]: d.pop(0, 'defalut') # 當刪除不存在的key, 並且指定了默認值時, 不會拋出KeyError, 並且返回默認值
Out[6]: 'defalut'
In [7]: d.pop(1, 'default') # 有沒有default, 是在key不存在的時候纔有所區別。
Out[7]: 'abc'
In [8]: d.popitem() # popitem隨機返回並刪除一個kv對的二元組
Out[8]: (2, 'abc')
In [9]: d.clear() # clear方法清空一個字典
In [10]: d.popitem() # 對空字典popitem, 將拋出KeyError
---------------------------------------------------------------------------
KeyError Traceback (most recent call last)
<ipython-input-10-5d3e77a54ba7> in <module>()
----> 1 d.popitem()
KeyError: 'popitem(): dictionary is empty'
In [12]: del d['c'] # 不過通常用pop刪除key
訪問
單個元素的訪問
- d['d']:通過key訪問value,當key不存在的時候拋出KeyError
- d.get('d'):get方法通過key訪問value,get方法訪問不存在的key的時候返回None
- d.get('c', 'default'):事實上get方法訪問不存在的key的時候, 返回默認值, 默認值默認爲None
- d.setdefault('c', 'default'):當一個key存在value的時候, 返回value, 如果不存在, 就添加其kv對。
In [2]: d = {'d': 2, 'p':0, 'r': 2}
In [3]: d['d'] # 通過key訪問value
Out[3]: 2
In [4]: d['c'] # 當key不存在的時候拋出KeyError
---------------------------------------------------------------------------
KeyError Traceback (most recent call last)
<ipython-input-4-3e4d85f12902> in <module>()
----> 1 d['c']
KeyError: 'c'
In [5]: d.get('d') # get方法通過key訪問value
Out[5]: 2
In [6]: d.get('c') # get方法訪問不存在的key的時候返回None
In [9]: d.get('c', 'default') # 事實上get方法訪問不存在的key的時候, 返回默認值, 默認值默認爲None
Out[9]: 'default'
d.setdefault:當一個key存在value的時候, 返回value, 如果不存在, 就添加其kv對。
In [10]: d.setdefault('c', 'default') # c不存在
Out[10]: 'default'
In [11]: d
Out[11]: {'c': 'default', 'd': 2, 'p': 0, 'r': 2}
In [12]: d.setdefault('d', 'default')
Out[12]: 2
setdefault的實現:
In [13]: def setdefault(d, k, default=None):
...: value = d.get(k, default)
...: d[k] = value
...: return value
...:
字典的遍歷
字典的元素是成對出現的
- 如果直接用for in遍歷字典, 遍歷的是字典的key
- d.values():value返回一個可迭代對象, 元素是字典的所有value
- items方法返回一個可迭代對象, 元素是字典的所有(k, v)對
- d.keys():eys方法返回一個可迭代對象, 元素是字典所有的key
In [14]: for x in d:
...: print(x)
...:
d
p
c
r
In [15]: d
Out[15]: {'c': 'default', 'd': 2, 'p': 0, 'r': 2}
直接用for in遍歷字典, 遍歷的是字典的key
In [17]: d.values() # value返回一個可迭代對象, 元素是字典的所有value
Out[17]: dict_values([2, 0, 'default', 2])
In [19]: for v in d.values(): # 返回values
...: print(v)
...:
2
0
default
2
In [20]: d.items() # items方法返回一個可迭代對象, 元素是字典的所有(k, v)對
Out[20]: dict_items([('d', 2), ('p', 0), ('c', 'default'), ('r', 2)])
In [21]: for x in d.items(): # key和value都出現
...: print(x)
...:
('d', 2)
('p', 0)
('c', 'default')
('r', 2)
In [22]: for k, v in d.items(): # key和value分開出現
...: print(k, v)
...:
d 2
p 0
c default
r 2
In [23]: d.keys() # keys方法返回一個可迭代對象, 元素是字典所有的key
Out[23]: dict_keys(['d', 'p', 'c', 'r'])
python2與Python3的不同
python2中返回的都是一個列表, python3中返回的是可迭代對象
區別:python3中的keys, values, items返回的都是生成器, 它並不會複製一份內存。
python2中對應的函數返回的是列表, 會複製一份內存。
Python 2.7.5 (default, Nov 6 2016, 00:28:07)
[GCC 4.8.5 20150623 (Red Hat 4.8.5-11)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> d = {'r': 2, 'd': 2, 'c': 3, 'p
File "<stdin>", line 1
d = {'r': 2, 'd': 2, 'c': 3, 'p
^
SyntaxError: EOL while scanning string literal
>>> d = {'r': 2, 'd': 2, 'c': 3, 'p': 0}
>>> type(d.keys())
<type 'list'>
>>> type(d.items())
<type 'list'>
>>> type(d.values())
<type 'list'>
字典的限制
- 字典是無序的
- 字典的key不能重複
- 字典的key需要可hash
In [24]: d = {}
In [25]: d[[1, 2, 3]] = 3 # 不可hash的key會報錯
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-25-1b5d054185d2> in <module>()
----> 1 d[[1, 2, 3]] = 3
TypeError: unhashable type: 'list'
In [26]: d[(1, 2, 3)] = 3
In [27]: d
Out[27]: {(1, 2, 3): 3}
In [28]: d[0] = [1, 2, 3] # 字典的value是沒有限制的
In [29]: d
Out[29]: {0: [1, 2, 3], (1, 2, 3): 3}
In [30]: hash(d) # 字典不是可hash的, 所以不能做set的元素
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-30-a37dc9dc2032> in <module>()
----> 1 hash(d)
TypeError: unhashable type: 'dict'
標準庫中兩個字典的變體
默認字典
- 默認字典的定義:d2 = defaultdict()
- 默認字典的初始值:defaultdict(None, {})
In [31]: from collections import defaultdict
In [32]: d1 = {} # 普通字典
In [33]: d2 = defaultdict() # 默認字典
In [34]: d1 # 普通字典的初始值
Out[34]: {}
In [35]: d2
Out[35]: defaultdict(None, {}) # 默認字典的初始值
In [40]: d2 = defaultdict(list)
In [41]: d1['a']
---------------------------------------------------------------------------
KeyError Traceback (most recent call last)
<ipython-input-41-a9ea8faf9ae0> in <module>()
----> 1 d1['a']
KeyError: 'a'
In [42]: d2['a'] # 得到一個list
Out[42]: []
default初始化的時候, 需要傳入一個函數, 這個函數也叫工廠函數, 當我們使用下標訪問一個key的時候, 如果這個key不存在, defaultdict會自動調用初始化時傳入的函數, 生成一個對象做爲這個key的value
In [43]: d = {}
...: for k in range(10):
...: for v in range(10):
...: if k not in d.keys():
...: d[k] = []
...: d[k].append(v)
...:
In [44]: d = defaultdict(list)
In [45]: for k in range(10):
...: for v in range(10):
...: d[k].append(v)
...:
有序字典
In [46]: from collections import OrderedDict
In [47]: d = OrderedDict()
In [48]: d[0] = 3
In [49]: d[3] = 4
In [50]: d
Out[50]: OrderedDict([(0, 3), (3, 4)])
In [51]: for k, v in d.items():
...: print(k, v)
...:
0 3
3 4
有序字典, 會保持插入順序
In [53]: def f():
...: print('f is called')
...: return 'a'
...:
In [54]: d = defaultdict(f)
In [55]: d['xxx']
f is called
Out[55]: 'a'
In [56]: d['yyy']
f is called
Out[56]: 'a'
In [57]: d['xxx']
Out[57]: 'a'
字典總結
字典:
增加/修改:
下標操作
update
刪除
pop()
有默認值
無默認值的區別
popitem
無序的
clear
del 語句
訪問:
單個元素:
下標
get
setdefault
遍歷:
keys
values
items
限制:
key必須是可hash