赞
踩
字典是python的内置基本数据类型之一,其他语言中可能会被称为“关联存储”或“关联数组”。它是一种映射关系,以包含在{}中的"键:值"对表示。字典是一种可变对象,键没有顺序。其主要用途是通过关键字存储、提取值。
目录
3.1.3 使用collections.OrderedDict容器数据类型
3.2.2 使用collections.defaultdict容器数据类型
字典有很多种创建方式,你可以直接以常量方式编写,或使用类构造器或字典推导式来创建字典。
字典是以{}包围的键值对,键和值以冒号分隔,键值对之间以逗号分隔,按这种格式可以直接编写出字典。
直接输入{}就初始化了一个空字典:
- d = {}
- type(d)
创建字典的同时输入键值:
- d = {'Vincent':1, 'Victor':2, 'Grace':3}
- type(d)
python中的另一种数据结构集合(Set)也是包含在{}中的,集合是唯一不可变对象的无序集合,但{}创建的是空字典,空集合必须要用set函数来创建。
s = set(['a', 'b', 'a'])
类构造器dict也可以创建字典,且兼容的输入形式更多。
直接调用dict()即初始化了一个空字典:
- d = dict()
- type(d)
可以用多种形式给dict()提供键值对,如:key=value, [(key, value) …] , zip()等,下面4种方式创建出来的字典是一样的:
- d1 = dict(Vincent=1, Victor=2, Grace=3)
-
- d2 = dict( [('Vincent', 1), ('Victor', 2), ('Grace', 3)] )
-
- d3 = dict( zip(['Vincent', 'Victor', 'Grace'], [1, 2 ,3]) )
-
- d4 = dict( {'Vincent':1, 'Victor':2}, Grace=3 )
字典推导式和列表与集合的推导式类似,它包含在{}中,需要以冒号分隔的2个变量,后面跟上for和if子句(if子句可省略),推导式会执行for循环将求得的值依次加入字典。
求10以内偶数的2次幂,并保存到字典中:
d = {x:x**2 for x in range(10) if x%2==0}
字典推导式另一个常见的用法是从其他字典中筛选子集,例如从d1中筛选value小于3的记录,保存一个子集:
- d1 = dict(Vincent=1, Victor=2, Grace=3)
-
- d5 = {k:v for k,v in d1.items() if v<3} # 字典推导式
-
- d5
字典提供了非常丰富的方法,部分常用的如下(d代表字典对象):
通过d.keys()遍历字典键,并使用d[key]获取键对应的值:
- for k in d1.keys():
- print(k,'=>' ,d1[k])
上面的示例也可用d.items()改写为,items()会以元组的方式返回键值对,需要2个参数:
- for k,v in d1.items():
- print(k, '=>', v)
get(key [, default]) 可以在key不存在时可以返回默认值而不是引发KeyError,这个特点非常适合用在统计场景,例如统计文章中每个单词出现的次数(这里用一句话代替):
- str = "How Many Cookies Could a Good Cook Cook if a Good Cook Could Cook Cookies?"
-
- l = str.split(' ') # 用空格拆分单词,得到单词的列表,这里没有去除标点
-
- d = {} # 构造一个空字典,用于存储单词及计数
-
- for word in l:
- d[word] = d.get(word, 0) + 1
d.pop(key [, default])和d.popitem() 是消耗性迭代,一个返回值,一个返回键值对组成的元组,用法类似。
字典的应用场景非常广泛,变化也非常多,下面介绍排序,多值映射,键值反转场景。
Python原生的字典对象是无序的,如果我们确实需要强调某种顺序的时候,可以使用某些方法来使字典保持有序。
一个常用的方法就是通过列表来进行间接排序(列表是有序的)。例如需要按键排序,可以先将字典键收集到列表中,使用列表的sort方法对键值排序,然后使用for循环遍历显示结果。
- d = dict(d=4, b=2, a=1, c=3)
- ks = list(d.keys())
- ks.sort()
-
- for key in ks:
- print(key, '=>', d[key])
也使用sorted内置函数一步完成,sorted()函数会对可迭代对象排序,并返回一个列表。由于字典本身就是可迭代对象,因此sorted(d)会直接返回排序后的键列表,我们直接遍历即可:
- d = dict(d=4, b=2, a=1, c=3)
-
- for key in sorted(d, reverse=True):
- print(key, '=>', d[key])
上面两种方法都是借助了其他有序的数据类型,在遍历字典时实现间接排序,如果想要字典本身保持有序,可以借助python标准库中的collections.OrderedDict。
这是dict的一个字类,可以用于构造有序字典。有序字典被设计用在强调排序的场景,例如在构造JSON这种需要保持顺序的数据时非常有用,其在效率上不如常规字典(有序字典内部会额外维护双向链表来保持元素顺序)。
有序字典构造方法和dict一样,但OrderedDict()会根据元素加入顺序来排列键值对:
- from collections import OrderedDict
- d = OrderedDict(a=1, b=2, c=3)
-
- d
OrderedDict也可以通过popitem()方法来返回并移除一个键值对,默认按LIFO先进后出方式从尾部返回键值对:
d.popitem()
通过参数last=False使用FIFO先进先出的方式从头部返回键值对:
d.popitem(last=False)
有序字典通过move_to_end(key [,last=True])方法还可以将指定元素移动到开头或结尾,默认将指定键值对移动到字典的结尾:
d.move_to_end('a')
如果last参数被设置为False,则会移动开头:
d.move_to_end('c', last=False)
通常情况下,键和值是一对一的关系。如果要实现一个键对应多个值,我们需要将多个值包装成一个整体(放入其他容器类型中)作为值。
我们可以将多个值放在其他容器类型中(列表/集合等),以一个整体作为值,如果需要保持多个值的顺序就用列表,需要保持值唯一就用集合:
- d1= dict(a=[1,2,1], b=[4,5,6], c=[7,7,7])
-
- d2= dict(a={1,2,1}, b={4,5,6}, c={7,7,7})
由于值是列表类型,可以使用列表的方法来修改值:
- d1['a']
-
- d1['a'].append(4)
-
- d1['a']
上面的示例是采用常量的方法将值编写为列表/集合的容器类型,但对于不存在的键,其值类型是未知的,无法直接调用列表/集合方法来添加值:
d1['x'].append(1) # 报错
你需要先初始化值的类型,才能调用相应的方法:
- d1['x'] = []
-
- d1['x'].append(1)
python的标准库提供了collections.defaultdict()来帮助你更方便的建立多值字典,其在初始化时可以指定值的容器类型。即默认的dict()构造的是"键-值"对,而collections.defaultdict(list)可以构造"键-列表"对或collections.defaultdict(set)构造"键-集合"对。
例如,构造一个键-列表对,对于值可以对值直接调用列表方法:
- from collections import defaultdict
-
- d3 = defaultdict(list)
-
- d3['x'].append(1)
或构造一个键-集合对,方式也一样:
- d4 = defaultdict(set)
-
- d4['y'].add(1)
通过使用defaultdict,可以省去每次新增一个键,都要显式声明其值的容器类型的操作。
字典的反转键值只需要分别将键(d.keys())和值(d.values())提取出来,通过zip函数构造出"值-键"对,即可实现键-值反转。
zip函数会在多个可迭代对象上并行迭代,并从每个迭代对象返回一个元素组成元组,例如:
- z = zip(['a','b','c'], [1,2,3])
-
- z
zip函数返回的也是一个可迭代对象,可以通过for循环进行遍历:
for k in z: print(k)
注意可迭代对象是消耗性的,遍历一次后就没了,如果要再次使用,需要使用zip函数重新构造:
for k in z: print(k)
了解了zip函数的功能,可以很方便通过d.keys(), d.values()和zip函数构造出一个键值反转的字典:
- d5 = dict(a=1, b=2, c=3)
-
- d5_reversed = dict(zip(d5.values(),d5.keys())) # d5.values()在前,d5.keys()在后
-
- d5_reversed
其他的方面的字典应用,如求交集,差集,最大值,最小值等,大多数都是围绕d.keys(), d.values(), d.items()这3个函数做文章,大家可以自行尝试。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。