首页 > 编程语言 > 详细

Python 进阶编程之字典的高级用法

时间:2020-04-26 17:18:42      阅读:59      评论:0      收藏:0      [点我收藏+]

一、 collections 中 defaultdict

1.1 字典的键映射多个值

将下面的列表转成字典

l = [(a,2),(b,3),(a,1),(b,4),(a,3),(a,1),(b,3)]

一个字典就是一个键对应一个单值的映射,而上面的列表中有相同键。如果你想要一个键映射多个值,那么就需要将这多个值放到另外的序列中,比如 list 或者 set 里面,像下面这样:

d = {
    a: [1, 2, 3],
    b: [4, 5]
}
e = {
    a: {1, 2, 3},
    b: {4, 5}
}

你可以很方便的使用 collections 模块中的 defaultdict 来构造这样的字典。defaultdict 的一个特征是它会自动初始化每个 key 刚开始对应的值。

In [1]: l = [(a,2),(b,3),(a,1),(b,4),(a,3),(a,1),(b,3)]

In [2]: from collections import defaultdict

In [3]: d = defaultdict(list)

In [4]: for key, value in l:
   ...:     d[key].append(value)
   ...: 

In [5]: d
Out[5]: defaultdict(list, {a: [2, 1, 3, 1], b: [3, 4, 3]})

当然这个默认的容器不一定是 list, 也可以是集合 set。根据自己的需求选择用 list 还是 set 。如果你想保持元素的插入顺序就应该使用列表,如果想去掉重复元素就使用集合!

1.2 统计字典中某个值出现的次数

来源于微信交流群里一个朋友工作中的问题,列表中有很多字典,需要统计字典中相同的键对应的值的和

技术分享图片

利用 defaultdict 设置默认值的方法 defaultdict(int),代码如下:

In [6]: d = defaultdict(int)

In [7]: objs = [{F29958SVDK6: 12}, {F29958SVDK6: 12}, {F29958SVDK6: 12}, {F29958SVDK6: 12}, {F29958SVDK6: 12}]

In [8]: for obj in objs:
   ...:     for key,value in obj.items():
   ...:         d[key] += value
   ...: 

In [9]: d
Out[9]: defaultdict(int, {F29958SVDK6: 60})

二、collections 创建有序字典

字典dict是无序的,如果我们想要有序的dict,可以使用OrdereDict 。示例如下:

In [11]: from collections import OrderedDict

In [12]: d = OrderedDict()

In [13]: d[bar] = 2

In [14]: d[non] = 8

In [15]: d[sek] = 5

In [16]: d
Out[17]: OrderedDict([(bar, 2), (non, 8), (sek, 5)])

OrderedDict 内部维护着一个根据键插入顺序排序的双向链表。每次当一个新的元 素插入进来的时候,它会被放到链表的尾部。对于一个已经存在的键的重复赋值不会 改变键的顺序。

需要注意的是,一个 OrderedDict 的大小是一个普通字典的两倍,因为它内部维 护着另外一个链表。所以如果你要构建一个需要大量 OrderedDict 实例的数据结构的 时候 (比如读取 100,000 行 CSV 数据到一个 OrderedDict 列表中去).

那么你就得仔细权衡一下是否使用 OrderedDict 带来的好处要大过额外内存消耗的影响。

2.1 改变 key-value 的顺序

OrderedDict 是有序的字典,同时也能改变其顺序。比如我们想要改变有序的 OrderedDict 对象的 key-value 顺序,可以使用 move_to_end(key)。还是以上面创建的有序字典为例子

In [18]: d.move_to_end("bar")

In [20]: d
Out[20]: OrderedDict([(non, 8), (sek, 5), (bar, 2)])

可以看到之前排在第一位的 bar被移到最后一位了。move_to_end 还接收一个关键字参数 last。last 默认为 True,当 last = False 的时候,表示将该键移动到最前面!

2.2 删除 key_value

如果我们要删除有序字典中的 key-value, 可以使用 popitem 方法, popitem(last=True) 按照先进后出的顺序删除 dict中 的 key-value,popitem(last=False) 按照先进先出的规则删除 dict 中的 key-value。

In [42]: d
Out[42]: OrderedDict([(bar, 2), (non, 8), (sek, 5)])

In [43]: d.popitem(last=False)
Out[43]: (bar, 2)

In [44]: d
Out[44]: OrderedDict([(non, 8), (sek, 5)])

三、字典排序

利用Python 内置函数 sorted 对字典的键或者值进行排序,首先来了解下 sorted 函数

sorted(iterable, key=None, reverse=False)

参数说明:

  • iterable -- 可迭代对象

  • key -- 主要是用来进行比较的元素,只有一个参数,具体的函数的参数就是取自于可迭代对象中,指定可迭代对象中的一个元素来进行排序。

  • reverse -- 排序规则,reverse = True 降序 , reverse = False 升序(默认)。

3.1 按照 key 进行排序

理解了 sorted 函数就好办了,代码如下:

In [55]: d = {b:3,a:4,c:2,d:1}

In [57]: d.items()
Out[57]: dict_items([(b, 3), (a, 4), (c, 2), (d, 1)])

In [58]: sorted(d.items(), key=lambda i:i[0])
Out[58]: [(a, 4), (b, 3), (c, 2), (d, 1)]

3.2 按照 value 进行排序

代码如下:

In [59]: sorted(d.items(), key=lambda i:i[1])
Out[59]: [(d, 1), (c, 2), (b, 3), (a, 4)]

注意排序后的返回值是一个list,而原字典中的名值对被转换为了list中的元组。

四、通过某个关键字排序一个字典列表

假设你有一个字典列表, 如下:

rows = [ {fname: Brian, lname: Jones, uid: 1003},
 {fname: David, lname: Beazley, uid: 1002},
 {fname: John, lname: Cleese, uid: 1001}, 
{fname: Big, lname: Jones, uid: 1004} ] 

你想根据某个或某几个字典字段来排序这个列表。

通过使用 operator 模块的 itemgetter 函数,可以非常容易的排序这样的数据结构,代码如下:

In [46]: from operator import itemgetter

In [47]: rows_by_fname = sorted(rows, key=itemgetter(fname))

In [48]: rows_by_fname
Out[48]: 
[{fname: Big, lname: Jones, uid: 1004},
 {fname: Brian, lname: Jones, uid: 1003},
 {fname: David, lname: Beazley, uid: 1002},
 {fname: John, lname: Cleese, uid: 1001}]

In [49]: rows_by_uid = sorted(rows, key=itemgetter(uid))

In [50]: rows_by_uid
Out[50]: 
[{fname: John, lname: Cleese, uid: 1001},
 {fname: David, lname: Beazley, uid: 1002},
 {fname: Brian, lname: Jones, uid: 1003},
 {fname: Big, lname: Jones, uid: 1004}]

itemgetter() 函数也支持多个 keys,比如下面的代码:

In [52]: rows_by_lfname = sorted(rows, key=itemgetter(lname,fname))

In [53]: rows_by_fname
Out[53]: 
[{fname: Big, lname: Jones, uid: 1004},
 {fname: Brian, lname: Jones, uid: 1003},
 {fname: David, lname: Beazley, uid: 1002},
 {fname: John, lname: Cleese, uid: 1001}]

 

 

 

Python 进阶编程之字典的高级用法

原文:https://www.cnblogs.com/kcxg/p/12780810.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!