字典術語:Dict-Mapping;Item-Entry
字典英文成爲Dict或者Dictionary,也稱作mapping。
Python中,字典是有任意個元素組成的集合,每個元素成爲一個Item,也成爲Entry。key+value組合構成了Item,即Entry。
Python字典的初始化
初始化方法一:dict(**kwargs),使用dict[name]=value完成字典的初始化
初始化方法二:dict(iterable,**kwarg),使用可迭代對象加dict[name]=value初始化字典,注意,這裏的iterable可迭代對象的元素必須是一個二元機構
初始化方法三:dict(mapping,**kwarg),使用字典構造另一個字典
>>> d1 = {}
官方推薦了幾種寫法:
>>> a = dict(one=1, two=2, three=3)
>>> b = {'one': 1, 'two': 2, 'three': 3}
>>> c = dict(zip(['one', 'two', 'three'], [1, 2, 3]))
>>> d = dict([('two', 2), ('one', 1), ('three', 3)])
>>> e = dict({'three': 3, 'one': 1, 'two': 2})
>>> a == b == c == d == e
True
#我們可以對照做練習:
>>> dn = dict(a=100,b=200)
>>> d4=dict(dn)
>>> d5 = dict(d4, a=300, b=400)
>>> d6=dict([('a',100),["b",200],(1,"abcde")],b=300,c=400)
>>> print(dn)
>>> print(d4)
>>> print(d5)
>>> print(d6)
{'a': 100, 'b': 200}
{'a': 100, 'b': 200}
{'a': 300, 'b': 400}
{'a': 100, 'b': 300, 1: 'abcde', 'c': 400}
>>> b = {'one': 1, 'two': 2, 'three': 3}
>>> b
{'one': 1, 'two': 2, 'three': 3}
類方法 dict.fromkeys(iterable, value):
>>> d = dict.fromkeys(range(5))
>>> d
{0: None, 1: None, 2: None, 3: None, 4: None}
>>> d = dict.fromkeys(range(3),0)
>>> d
{0: 0, 1: 0, 2: 0}
Python字典元素的訪問
len(d)
Return the number of items in the dictionary d.
d[key]
Return the item of d with key key. Raises a KeyError if key is not in the map.
這種方法,當key不存在時候就會返回KeyError
get(key[,default])
這種方法在key不存在時候,就不會返回KeyError了,而是可以返回一個默認的值。例如:
>>> d.get(9,"返回默認值,並沒有設置哦")
'返回默認值,並沒有設置哦'
# 查看一下現在的d,確認返回值沒有被添加到字典裏
>>> d
{0: 0, 1: 0, 2: 0}
setdefault(key,“設置的默認值”)
setdefault方法,當key不存在時候就添加鍵值對,value設置爲default,並且返回default;
如果default沒有設置,那麼缺省值我None。
>>> d.setdefault(10,"設置默認的值")
'設置默認的值'
>>> d # 對比d.get ,default的值設置進了字典d
{0: 0, 1: 0, 2: 0, 10: '設置默認的值'}
Update
>>> d = {"a","b"}
>>> d1=[12,34]
>>> d.update(d1)
>>> d
{12, 34, 'a', 'b'}
Python字典的刪除
pop(key[,default])
key存在就移除它,並返回它的value
key不存在,就返回給定的default
如果default沒有設置,那麼,key不存在時候就會報出KeyError異常錯誤
popitem()
移除並返回一個任意值的鍵值對
字典如果爲empty,則拋出KeyError異常
>>> d = {"a":1,"b":2}
>>> d.popitem()
('b', 2)
clear
清空字典
遍歷
1. 遍歷key
>>> d = {}
>>> for i in range(5):
>>> d[i]=i+10
>>> d
{0: 10, 1: 11, 2: 12, 3: 13, 4: 14}
>>> for k in d:
>>> print(k)
0
1
2
3
4
>>> for k in d.keys():
>>> print(k)
0
1
2
3
4
2. 遍歷value
>>> for v in d.values():
>>> print(v)
10
11
12
13
14
>>> for k in d.keys():
>>> print(d[k])
>>> print(d.get(k))
10
10
11
11
12
12
13
13
14
14
遍歷字典的items
利用items方法把字典的鍵和值提取出來的方法
>>> for item in d.items():
>>> print(item)
(0, 10)
(1, 11)
(2, 12)
(3, 13)
(4, 14)
>>> for k,v in d.items():
>>> print(k,v)
0 10
1 11
2 12
3 13
4 14
>>> for k,_ in d.items():
>>> print(k)
0
1
2
3
4
>>> for _,k in d.items():
>>> print(k)
10
11
12
13
14
Python3中, keys, values, items方法返回一個類似一個生成器的可迭代對象
- Dictionary view對象,可以使用len(), iter(), in操作
- 字典的entry的動態的視圖,字典變化,視圖將反映出這些變化
- keys返回一個類set對象,也就是可以看做一個set集合。如果values都可以hash,那麼items也可以看做是類set對象
Python2中,上面的方法會返回一個新的列表,立即佔據新的內存空間。所以Python2建議使用
iterkeys, itervalues, iteritems版本,返回一個迭代器,而不是返回一個copy
遍歷與刪除
d = dict(a = 10, b = 20, c = 30)
d
{'a': 10, 'b': 20, 'c': 30}
在刪除字典元素過程中,需要使用keys方法,這個過程不能改變字典的size,比如錯誤的做法:
pop按照key彈出:
# for k,v in d.items():
# print(d.pop(k)) # 錯誤的做法,會引起size changed 異常
d = {
1:0,
2.0:3,
"digital":None,
("hello","sales","I"):"client",
b"a":"334455"
}
d
{1: 0,
2.0: 3,
'digital': None,
('hello', 'sales', 'I'): 'client',
b'a': '334455'}
# 這個方法就不會破壞字典的size,不過僅做說明只用,因爲這樣做就等效於clear
>>> while len(d):
>>> print(d.popitem())
>>> d
#這裏返回的是一個惰性對象
(b'a', '334455')
(('hello', 'sales', 'I'), 'client')
('digital', None)
(2.0, 3)
(1, 0)
{}
key的理解
字典的key要求與set元素的要求是一致的:
- set元素就可以看做key,可以把set理解爲dict的簡化版
- hashable可哈希的纔可作爲key,所以在使用某對象作爲字典key之前,可以用hash做測試
- 使用key訪問,就如同列表使用index一樣,時間複雜度是O(1),這是我們推薦使用的訪問元素的方式,例如:
>>> d = {
1:0,
2.0:3,
"digital":None,
("hello","sales","I"):"client",
b"a":"334455"
>>> }
>>> d
{1: 0,
2.0: 3,
'digital': None,
('hello', 'sales', 'I'): 'client',
b'a': '334455'}
>>> d1 = {
2.0:3,
"digital":None,
("hello","sales","I"):"client",
b"a":"334455"
>>> }
>>> d1
{2.0: 3, 'digital': None, ('hello', 'sales', 'I'): 'client', b'a': '334455'}
>>> d2 = {
"digital":None,
("hello","sales","I"):"client",
b"a":"334455"
>>> }
>>> d2
{'digital': None, ('hello', 'sales', 'I'): 'client', b'a': '334455'}
>>> d1.keys()-d2.keys() #可以用減號運算
{2.0}
Python字典有序性的理解
Python字典是按照key的hash值無序存儲的
但有時候我們需要一個有序的元素順序,在Python3.6之前,使用OrderedDict就可以實現;
到Python3.6開始dict自身支持元素按照生成的先後順序排序;
但是,3.6之後是否還會繼續支持dict按照生成順序排序呢?我們不確定,所以,建議還是按照不知道Python3.6的這個屬性學習和處理。
我們閒聊瞭解一下到底Python對無序數據結構記錄了什麼順序?
當我們使用Python3.5 的版本時候,Python 3.6之前,在不同的機器上,甚至同一個程序分別運行2次,都不能確定不同的key的先後順序。
C:\Python\Python353>python Python 3.5.3
>>> d = {"a":100,"b":200, "c": 300, "d": 400}
>>> print(d)
{'a': 100, 'b': 200, 'c': 300, 'd': 400}
這個輸出結果不是固定的,有可能是:
{ ‘b’: 200,‘a’: 100, ‘c’: 300, ‘d’: 400}
也有可能是:
{ ‘b’: 200,‘a’: 100, ‘c’: 300, ‘d’: 400}
這時候我們需要使用OrderedDict模塊:
>>> from collections import OrderedDict
>>> orderd = OrderedDict()
>>> orderd["b"] =200
>>> orderd["c"] = 300
>>> orderd["a"] = 100
>>> orderd["d"] =400
>>> print(orderd) # 這時候輸出結構就是按照輸入的順序
OrderedDict([('b', 200), ('c', 300), ('a', 100), ('d', 400)])
如上注意,它輸出的其實是線性數據解構,即告訴你它的輸出是有順序的。
當然,Python3.6記錄了Python字典key的錄入順序,遍歷的時候,也是按照這個順序,例如下面的輸出結果一定是固定的,不會像Python3.5那樣變:
>>> d = {"a":100,"b":200, "c": 300, "d": 400}
>>> print(d)
{'a': 100, 'b': 200, 'c': 300, 'd': 400}
目前,建議不要3.6提供的這種字典特性,還是以爲字典返回的是無序的。如果非要這種有序,建議使 用OrderedDict。
defaultdict
Python字典的defaultdict其實就是實現給字典的key附默認的值,以下面的代碼爲例:當d1中k不存在的時候,先創建k和[]空列表鍵值對,然後爲列表增加元素。最後,得到{‘l’: [0, 1, 2], ‘o’: [0, 1, 2], ‘v’: [0, 1, 2], ‘e’: [0, 1, 2]}
>>> d1 = {}
>>> for k in 'love':
>>> for v in range(3):
>>> if k not in d1.keys():
>>> d1[k] = []
>>> d1[k].append(v)
>>> print(d1)
{'l': [0, 1, 2], 'o': [0, 1, 2], 'v': [0, 1, 2], 'e': [0, 1, 2]}
Python提供了defaultdict默認的類,即defaultdict(default_factory)構造一個特殊字典,初始化是可以傳入一個工廠函數,當訪問一個不存在的key是,就會調用這個工廠函數獲得返回值,和key湊成鍵值對,例如:
>>> from collections import defaultdict
>>>
>>> d2 = defaultdict(list)
>>> print(d2["a"]) #創建鍵值對
>>> print(d2) # 這樣就發現獨立一個鍵值對
[]
defaultdict(<class 'list'>, {'a': []})
>>> from collections import defaultdict
>>> # d2 = defaultdict(list)
>>> for k in "love":
>>> for v in range(3):
>>> d2[k].append(v) #
>>> print(d2)
defaultdict(<class 'list'>, {'a': [], 'l': [0, 1, 2], 'o': [0, 1, 2], 'v': [0, 1, 2], 'e': [0, 1, 2]})
拓展閱讀https://blog.csdn.net/Alen_1996/article/details/87916039