1 解包

所谓解包,就是将字典通过 ** 操作符转为 Key=Value 的形式,这种形式可以直接传给函数作为关键字参数。

说说适用的几种情况。

1.1 搜索拼接条件

当应用中使用类似 SQLAlchemy 的 ORM 形式读取数据的时候,不同搜索条件,传入给 ORM 的搜索参数也随之改变。

下面是图书表的部分数据(只展示了部分字段)

  1. +----+---------------+-------------------------+-------+
  2. | id | category_name | book_name | price |
  3. +----+---------------+-------------------------+-------+
  4. | 1 | 人文社科 | 人类简史 | 42.90 |
  5. | 2 | 人文社科 | 世界简史 | 25.50 |
  6. | 3 | 经济管理 | 极致产品 | 37.00 |
  7. | 4 | 经济管理 | 史蒂夫·乔布斯传 | 44.20 |
  8. | 5 | 经济管理 | 影响力 | 41.20 |
  9. +----+---------------+-------------------------+-------+

搜索时,我们会以这样的形式执行查询方法

  1. books = Book.query.filter_by(id=1, book_name='影响力').all()

但是由于传入参数会根据搜索条件的变化而变化,无法直接写出有哪些参数,这个时候就可以使用字典解包

  1. condition = {}
  2. if book_id:
  3. condition['id'] = id
  4. if book_name:
  5. condition['name'] = book_name
  6. books = Book.query.filter_by(**condition).all()

这样就 OK 了

1.2 方法参数太多,为代码美观使用

  1. new_book = Book(category_name='文学小说', book_name='解忧杂货店', price=28.8,
  2. ...)
  3. db.session.add(new_book)

改成这样的话,美观一些

  1. book_param = {'category_name': '文学小说', 'book_name': '解忧杂货店', 'price': 28.8,
  2. ...}
  3. new_book = Book(**book_param)
  4. db.session.add(new_book)

并且,在上述新增图书过程中,都会对提交的参数进行校验,而校验方法返回的结果(也就是 book_param 和其它信息)一般也都是字典,所以使用字典解包的方式更符合实际场景。

总之,适当使用字典解包对方法进行传参,可以让我们的代码更灵活。

2 setdefault() 的使用

先看下这个方法怎么使用

dict.setdefault(key, default=None)

如果字典中包含有给定键,则返回该键对应的值,否则返回为该键设置的值。

很多时候我们需要对列表根据元素的某个 key 转化成一个包含列表的字典。比如,上面的数据中,我希望得到一个字典,字典的 key 是图书分类,value 是属于该分类的图书列表。我们通常会这样写

  1. books_dict = {}
  2. for book in book_list:
  3. if book['category_name'] not in books_dict.keys():
  4. books_dict[book['category_name']] = []
  5. books_dict[book['category_name']].append(book)

当然,这样写是正确的,能得到预期结果

  1. {
  2. "人文社科": [{
  3. "id": 1,
  4. "category_name": "人文社科",
  5. "book_name": "人类简史",
  6. "price": 42.9
  7. }, {
  8. "id": 2,
  9. "category_name": "人文社科",
  10. "book_name": "世界简史",
  11. "price": 25.5
  12. }],
  13. "经济管理": [{
  14. "id": 3,
  15. "category_name": "经济管理",
  16. "book_name": "极致产品",
  17. "price": 37.0
  18. }, {
  19. "id": 4,
  20. "category_name": "经济管理",
  21. "book_name": "史蒂夫·乔布斯传",
  22. "price": 44.2
  23. }, {
  24. "id": 5,
  25. "category_name": "经济管理",
  26. "book_name": "影响力",
  27. "price": 41.2
  28. }]
  29. }

但是如果使用字典的 setdefault() 方法话,可以少写几行代码,看起来也优雅一些

  1. books_dict = {}
  2. for book in book_list:
  3. books_dict.setdefault(book['category_name'], []).append(book)

3 字典合并

常用的合并方式

  1. # new_dict = {**dict1, **dict2, ...}
  2. # 合并多个字典,如果字典中存在相同的 key 的话,后面的会覆盖掉前面的
  3. # 比如 dict2 会覆盖 dict1 中的 key 相同的值
  4. >>> a = {'name': 'x', 'age': 13}
  5. >>> b = {'name': 'y'}
  6. >>> c = {**a, **b}
  7. >>> c
  8. {'name': 'y', 'age': 13}
  9. # dict1.update(dict2)
  10. # 合并两个字典,如果字典中存在相同的 key 的话,dict2 会覆盖 dict1 的对应值
  11. # 理解为更新某个字典应该更合适
  12. >>> a.update(b)
  13. >>> a
  14. {'name': 'y', 'age': 13}

有时我们碰到合并字典的情况也不少。比如,我们准备根据一本书的基本信息创建一本新书

  1. # to_dict 将 ORM 对象转为字典,是自定义的,理解意思就好
  2. base_book = Book.query.filter_by(id=1).first().to_dict()
  3. # 提交的参数需要校验,校验成功后返回值包含 book_param ,内容和下面类似
  4. book_param = {'book_name': '国家宝藏', 'price': 55.60}
  5. # 同时需要更新新书的创建时间和更新时间
  6. time_param = {'created_at': current_time, 'updated_at': current_time}
  7. # 新增书籍
  8. new_book = Book(**{**base_book, **book_param, **time_param})
  9. db.session.add(new_book)

当然,如果只是合并两个字典的话,也可以使用 update() 方法。

假设我们只需要合并 base_bookbook_param

  1. base_book.update(book_param)

这也可以工作,不过要注意,这样会修改 base_book 中的值。

如果只是单纯的更新某个字典的信息的话,update() 方法显然最合适。对于当前需求的话,还是第一种方式更合适。

本文首发于公众号「小小后端」,关注并回复「HMPython2018」领取 18 年很赞的 Python 学习教程。

Python中使用字典的几个小技巧的更多相关文章

  1. Python中实用却不常见的小技巧

    https://mp.weixin.qq.com/s?__biz=MzI5NDY1MjQzNA==&mid=2247489061&idx=2&sn=65cec7fa471b1e ...

  2. 如何将xml转为python中的字典

    如何将xml转为python中的字典 import cElementTree as ElementTree class XmlListConfig(list): def __init__(self, ...

  3. Python中的字典与集合

    今天我们来讲一讲python中的字典与集合 Dictionary:字典 Set:集合 字典的语法: Dictionary字典(键值对) 语法: dictionary = {key:value,key: ...

  4. [转]11个教程中不常被提及的JavaScript小技巧

    原文地址: https://www.cnblogs.com/ld1024/p/10723827.html 这次我们主要来分享11个在日常教程中不常被提及的JavaScript小技巧,他们往往在我们的日 ...

  5. 11个教程中不常被提及的JavaScript小技巧

    这次我们主要来分享11个在日常教程中不常被提及的JavaScript小技巧,他们往往在我们的日常工作中经常出现,但是我们又很容易忽略. 1.过滤唯一值 Set类型是在ES6中新增的,它类似于数组,但是 ...

  6. 「Python-Django」Django中使用数据库的 9 个小技巧

    Django 中使用数据库的 9 个小技巧. 1. 过滤器聚合 在 Django 2.0 之前,如果你想得到“用户总数”.“活跃用户总数”等信息时,你不得不使用条件表达式. Django 2.0 中, ...

  7. python中的字典(dict),列表(list),元组(tuple)

    一,List:列表 python内置的一种数据类型是列表:list.list是一种有序的数据集合,可以随意的添加和删除其中的数据.比如列出班里所有的同学的名字,列出所有工厂员工的工号等都是可以用到列表 ...

  8. 13.python中的字典

    字典其实和之前的元祖和列表功能相似,都是用来储存一系列对象的.也就是一种可变容器,或者是我所比喻的革新派的菜单. 但也不是完全相同,我在之前曾经将字典称为特殊的'序列',是字典拥有序列的部分特性,但是 ...

  9. python中 字符 字典 列表之间的转换

    1 字典 转 字符 定义一个字典:dict = {'name': 'python', 'age': 7}字典转字符 可以使用str强制转换 如: str(dict) 此时dict的类型就是字符型了 2 ...

随机推荐

  1. Python列表的深度排序

    实例1:>>>L = [2,3,1,4]>>>L.sort()>>>L>>>[1,2,3,4] 实例2:>>> ...

  2. Vue躬行记(1)——数据绑定

    Vue.js的核心是通过基于HTML的模板语法声明式地将数据绑定到DOM结构中,即通过模板将数据显示在页面上,如下所示. <div id="container">{{c ...

  3. 从无到有,构建GIS + BIM大厦

    声明:本文是一个系列原创(作者在GIS+BIM行业已有从业15年有余,还是个行业的小学生,文章内容不免有错误或者不当之处,敬请理解),旨在通过这个系列打造一个高性能,高可扩展的GIS+BIM框架,抛砖 ...

  4. 快学Scala 第二十课 (trait的构造顺序)

    trait的构造顺序: 首先调用超类构造器 特质构造器在超类构造器之后,类构造器之前执行 特质从左向右被构造 每个特质当中,父特质先被构造 如果多个特质共有一个父特质,而那个父特质已经被构造,则不会被 ...

  5. openpyxl中遇到TypeError: 'generator' object is not subscriptable的问题和解决方案

    今天在搭建驱动数据框架用到了一个叫 openpyxl的包用来解析excel数据 随后就出现了TypeError: 'generator' object is not subscriptable的bug ...

  6. 数据的异构实战(一) 基于canal进行日志的订阅和转换

    什么是数据的异构处理.简单说就是为了满足我们业务的扩展性,将数据从某种特定的格式转换到新的数据格式中来. 为什么会有这种需求出现呢? 传统的企业中,主要都是将数据存储在了关系型数据库中,例如说MySQ ...

  7. kafka-0.10.2.1:Producer生产时无法自动创建Topic

    集群环境: CenterOS 1台 Kafka:0.10.2.1版本. 今天在测试环境下,我们的Kafka集群工作不正常,具体现象为,使用confulentkafka向kafka集群生产消息失败,且并 ...

  8. MakaJs:基于 React, Redux 的轻量级前端框架

    github: maka.js 留下您宝贵的STAR!谢谢 maka maka源于中文码咖,意为写代码的大咖 一眼即可看懂的前端框架,简约而不简单 1.安装 bash sudo npm i -g @m ...

  9. FLask中蓝图(用于分文件)

    一,不使用蓝图,自己分文件 目录结构 -templates -views -__init__.py -user.py -order.py -app.py app.py from views impor ...

  10. LeetCode初级算法--链表02:合并两个有序链表

    LeetCode初级算法--链表02:合并两个有序链表 搜索微信公众号:'AI-ming3526'或者'计算机视觉这件小事' 获取更多算法.机器学习干货 csdn:https://blog.csdn. ...