08-02字典

字典

字典是一種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
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章