08-02字典

字典

字典是一种key-value结构

字典对象操作

新建字典

  • 方式1:d = {}
  • 方式2:d = dict()
  • 方式3:d =
  • 方式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
posted @ 2020-06-04 07:11  此时  阅读(98)  评论(0编辑  收藏  举报