字典dict
概念
在Python中字典属于一种映射类型,它和set相同,同样属于非线性结构存储
- 一个映射对象映射一个可hash的值到任意一个对象上去
- 映射是可变的对象
- dict是当前唯一一个标准的映射类型
- 字典的键几乎可以任意的值
- 字典的值可以不必可hash,也就是说值可以是列表,字典,或者其他任意可变的对象
- 如果key相同,那么后面的value将会覆盖先前的value
- 不建议使用float类型作为字典的key
- key-value键值对的数据的集合
- 可变的, 无序的, key不重复
- 字典的key必须是可hash对象
简单来说:字典是由key:value键值对组成的数据的集合,它的主要特点是 可变的、无序的、不重复的
字典是除set集合以外另一种可变的非线性容器模型,在Python中非常强大,适合各种结构数据的存储、嵌套等
字典dict定义, 初始化
-
d = dict{} 或者 d = {}
-
dict(**kwargs)使用name = value初始化一个字典
d = dict(a=1,b=2) print(d) 运行结果: {'a': 1, 'b': 2}
-
dict(iterable, **kwargs)使用可迭代对象和name = value构造字典, 不过可迭代对象的元素必须是一个二元结构
d = dict([('a',1),('b',2)], c=3, d=4) print(d) 运行结果: {'a': 1, 'b': 2, 'c': 3, 'd': 4}
- d = dict(((‘1’, ‘a’), (‘2’, ‘b’)))
- d = dict(([‘1’, ‘a’], [‘2’, ‘b’]))
-
dict(mapping, **kwargs) 使用一个字典构造另外一个字典
d4 = dict([('a', 1),('b', 2)], c=3, d=4) d5 = dict(d4, e=5, f=6) print(d5) 运行结果: {'a': 1, 'b': 2, 'c': 3, 'd': 4, 'e': 5, 'f': 6}
-
d = {‘a’:10, ‘b’:20, ‘c’:None, ‘d’:[1, 2, 3]}
-
类方法dict.fromkey(iterable, value), 使用可迭代对象的值作为key, value默认为0, 否则使用指定的value对字典进行初始化
- d = dict.fromkeys(range(5))
- d = dict.fromkeys(range(5), 0)
d1 = dict.fromkeys(range(5)) d2 = dict.fromkeys(range(5), 0) print(d1) print(d2) 运行结果: {0: None, 1: None, 2: None, 3: None, 4: None} {0: 0, 1: 0, 2: 0, 3: 0, 4: 0}
字典的访问
- d[key]
- 返回可以对应的value
- key不存在则抛KeyErro异常
- get(key[, default])
- 返回key对应的值
- key不存在不会报KeyErro, 返回缺省值, 如果没有设置缺省值就返回None
- dict.setdefault(key[, default])
- 返回key对应的值value
- key不存在,添加key:value键值对(value设置为default),并返回value
- 如果default没有设置缺省为None
d = {'a': 1, 'b': 2} print(d.setdefault('a')) print(d.setdefault('f')) print(d) 运行结果: 1 None {'a': 1, 'b': 2, 'f': None}
字典的增加和修改
- d[key] = value
- 将key对应的值修改为value
- key不存在添加新的kv对
- update([other]) -> None
- 使用另一个字典的kv更新本字典
- key不存在, 就添加
- key存在, 覆盖已经存在的key对应的值
- 就地修改
d = dict([('a', 1), ('b', 2)], c=3, d=4) d.update(red=1) print(d) 运行结果: {'a': 1, 'b': 2, 'c': 3, 'd': 4, 'red': 1} d.update((('red',2),)) print(d) 运行结果: {'a': 1, 'b': 2, 'c': 3, 'd': 4, 'red': 2} d.updata({'blue':4}) print(d) 运行结果: {'a': 1, 'b': 2, 'c': 3, 'd': 4, 'red': 2, 'blue': 4}
字典的删除
- pop(key[, default])
key存在, 移除并返回它的值value, 否则返回给定的default(若default未设置, 且key不存在则抛出KeyErro异常) - popitem()
- 移除并返回一个任意键值对
- 字典为empty, 则抛出KeyErro异常
- clear()
清空字典d = dict([('a', 1), ('b', 2)], c=3, d=4) f = {} print(d.pop('a')) print(d.popitem()) print(f.popitem()) 运行结果: 1 ('d', 4) Traceback (most recent call last): File "C:/Users/刘鑫/PycharmProjects/p20/冒泡排序.py", line 6, in <module> print(f.popitem()) KeyError: 'popitem(): dictionary is empty'
- del语句
变量的通用删除方法, 本质上是减少一个对象的引用, 实际上删除的是名称, 而不是对象
字典的遍历
- for … in dict
- 遍历key
d = {'a': 1, 'b': 2, 'c': 3, 'd': 4, 'red': 1} for k in d: print(k) for k in d.keys(): print(k) 运行结果: a b c d red a b c d red
- 遍历value
d = {'a': 1, 'b': 2, 'c': 3, 'd': 4, 'red': 1} for k in d: print(d[k]) for k in d.keys(): print(d.get(k)) for v in d.values(): print(v) 运行结果: 1 2 3 4 1 1 2 3 4 1 1 2 3 4 1
- 遍历item, 即k, v 对
d = {'a': 1, 'b': 2, 'c': 3} for item in d.items(): print(item) for item in d.items(): print(item[0], item[1]) for k, v in d.items(): print(k, v) for _, v in d.items(): print(v) for k, _ in d.items(): print(k) 运行结果: ('a', 1) ('b', 2) ('c', 3) a 1 b 2 c 3 a 1 b 2 c 3 1 2 3 a b c
- 总结
- Python3中, keys, values, items方法返回一个类似生成器的可迭代对象, 不会把函数的返回结果复制到内存中
- 返回的Dictionary view对象, 可以使用len(), iter(), in操作
- 字典的entry的动态的视图, 字典的变化, 视图将反射出这些变化
- 如果values都可以hash, nameitems也可以看做是类set对象
- Python2中, 上面的方法会返回一个新的列表, 占据新的内存空间, 所以Python建议使用iterkeys, itervalues, iteritems, 返回一个迭代器, 而不是返回一个copy
- 遍历key
字典的遍历和移除
- 如何在遍历字典的时候移除元素
d = {'a': 1, 'b': 2, 'c': 3} keys = [] for k,v in d.items(): if isinstance(v, str): keys.append(k) for k in keys: d.pop(k) print(d)
字典的key
- key的要求和set的元素要求一致
- set的元素可以看做key, set可以看做是dict的简化版
- hashable可哈希才可以作为key, 可以使用hash()测试
- d = {1:0, 2.0:3, ‘abc’:None, {‘hello’, ‘world’, ‘python’}:‘string’, b’abc’:‘135’}
defaultdict
- collection.defaultdict([default_factory[, …]])
- 第一个参数是default_factory, 缺省值是None, 它提供一个初始化函数, 当key不存在时, 会调用这个工厂函数来生成key对应的value
- 构建一个字典, values是列表, 为其添加随机个元素
from collections import defaultdict import random d1 = {} for k in 'abcdef': for v in range(random.randint(1, 5)): if k not in d1.keys(): d1[k] = [] d1[k].append(v) print(d1) print('***********') d2 = defaultdict(list) #list:是default_factory, 生成对应的value for k in 'abcdef': for v in range(random.randint(1, 5)): d2[k].append(v) print(d2) 运行结果: {'a': [0, 1]} {'a': [0, 1], 'b': [0, 1, 2, 3]} {'a': [0, 1], 'b': [0, 1, 2, 3], 'c': [0, 1, 2]} {'a': [0, 1], 'b': [0, 1, 2, 3], 'c': [0, 1, 2], 'd': [0, 1, 2, 3, 4]} {'a': [0, 1], 'b': [0, 1, 2, 3], 'c': [0, 1, 2], 'd': [0, 1, 2, 3, 4], 'e': [0]} {'a': [0, 1], 'b': [0, 1, 2, 3], 'c': [0, 1, 2], 'd': [0, 1, 2, 3, 4], 'e': [0], 'f': [0, 1, 2, 3]} *********** defaultdict(<class 'list'>, {'a': [0]}) defaultdict(<class 'list'>, {'a': [0], 'b': [0, 1, 2, 3]}) defaultdict(<class 'list'>, {'a': [0], 'b': [0, 1, 2, 3], 'c': [0, 1]}) defaultdict(<class 'list'>, {'a': [0], 'b': [0, 1, 2, 3], 'c': [0, 1], 'd': [0, 1]}) defaultdict(<class 'list'>, {'a': [0], 'b': [0, 1, 2, 3], 'c': [0, 1], 'd': [0, 1], 'e': [0]}) defaultdict(<class 'list'>, {'a': [0], 'b': [0, 1, 2, 3], 'c': [0, 1], 'd': [0, 1], 'e': [0], 'f': [0]}) Process finished with exit code 0
Ordereddict
- collections.OrderedDict([items])
- key并不是按照加入的顺序排序, 可以使用OrderedDict记录顺序
from collections import OrderedDict import random d = {'banana': 3, 'apple': 4, 'pear': 1, 'orange': 2} print(d) keys = list(d.keys()) random.shuffle(keys) print(keys) od = OrderedDict() for key in keys: od[key] = d[key] print(od) print(od.keys()) 运行结果: {'banana': 3, 'apple': 4, 'pear': 1, 'orange': 2} ['orange', 'apple', 'banana', 'pear'] OrderedDict([('orange', 2), ('apple', 4), ('banana', 3), ('pear', 1)]) odict_keys(['orange', 'apple', 'banana', 'pear']) Process finished with exit code 0
- 有序字典可以记录元素的插入顺序, 打印的时候也按照这个顺序输出打印
- Python3.6版本字典会记录key的插入顺序(ipython不一定有效)
- key并不是按照加入的顺序排序, 可以使用OrderedDict记录顺序