文章目录

  • 1 问题
  • 2. 解决方案
  • 3. 讨论

1 问题

你有一个元素均为字典或其他类型的序列,你希望根据每个元素中的同一个字段(例如:日期)对序列中的所有元素进行分组迭代。

2. 解决方案

itertools 模块中的类 groupby 可以容易地实现上述需求。例如,假设你有类似下列格式的列表:

rows = [{'address': '5412 N CLARK', 'date': '07/01/2012'},{'address': '5148 N CLARK', 'date': '07/04/2012'},{'address': '5800 E 58TH', 'date': '07/02/2012'},{'address': '2122 N CLARK', 'date': '07/03/2012'},{'address': '5645 N RAVENSWOOD', 'date': '07/02/2012'},{'address': '1060 W ADDISON', 'date': '07/02/2012'},{'address': '4801 N BROADWAY', 'date': '07/01/2012'},{'address': '1039 W GRANVILLE', 'date': '07/04/2012'},
]

假定你希望按照日期对上述数据进行分组。对此,你可以先将上述数据按照每个字典的 date 域进行排序,然后使用 itertools.groupby 类创建一个迭代器:

>>> from operator import itemgetter
>>> from itertools import groupby>>> # 按照 date 字段进行排序
>>> rows.sort(key=itemgetter('date'))
>>> # 对数据进行迭代分组
>>> for date, items in groupby(rows, key=itemgetter('date')):
...    print(date)
...    for item in items:
...        print('\t', item)

上述代码的输出结果如下:

07/01/2012{'address': '5412 N CLARK', 'date': '07/01/2012'}{'address': '4801 N BROADWAY', 'date': '07/01/2012'}
07/02/2012{'address': '5800 E 58TH', 'date': '07/02/2012'}{'address': '5645 N RAVENSWOOD', 'date': '07/02/2012'}{'address': '1060 W ADDISON', 'date': '07/02/2012'}
07/03/2012{'address': '2122 N CLARK', 'date': '07/03/2012'}
07/04/2012{'address': '5148 N CLARK', 'date': '07/04/2012'}{'address': '1039 W GRANVILLE', 'date': '07/04/2012'}

需要说明的是,关于 itemgetter 的使用方法和源码分析可以参考【Python 每日一技】针对元素为字典的列表按照共同的键进行排序。

3. 讨论

在使用 itertools.groupby 创建实例的过程中,该实例会扫描可迭代对象也即给定的序列,同时查找具有某相同数据域(该数据域由 key 接受的函数指定)的元素(上述案例中每个元素都是字典)。

最终使用该类创建的对象是一个迭代器,在每对该迭代器进行一次迭代时,都会返回一个元组,元组有两个值:

  • 第一个值是某数据域(在上述案例中是日期);
  • 第二个值又是一个迭代器,在对此迭代器迭代时会生成若干个具有相同某数据域的元素(在上述案例中每个元素都是字典)。

需要注意的是,如果希望得到期望的结果,那么第一步需要将待分组的序列按照元素的某公共数据域进行排序,因为 groupby 在创建对象过程中只会检查相邻的元素是否具有相同的某公共数据域。

如果你的目的仅仅是为了将数据进行分组用于后续的随机访问,可能你使用 collections 模块中的 defaultdict 类创建一个多值字典更加合适。例如:

>>> from collections import defaultdict
>>> rows_by_date = defaultdict(list)
>>> for row in rows:
...    rows_by_date[row['date']].append(row)>>> rows_by_date
defaultdict(<class 'list'>, {'07/01/2012': [{'address': '5412 N CLARK', 'date': '07/01/2012'}, {'address': '4801 N BROADWAY', 'date': '07/01/2012'}], '07/02/2012': [{'address': '5800 E 58TH', 'date': '07/02/2012'}, {'address': '5645 N RAVENSWOOD', 'date': '07/02/2012'}, {'address': '1060 W ADDISON', 'date': '07/02/2012'}], '07/03/2012': [{'address': '2122 N CLARK', 'date': '07/03/2012'}], '07/04/2012': [{'address': '5148 N CLARK', 'date': '07/04/2012'}, {'address': '1039 W GRANVILLE', 'date': '07/04/2012'}]})>>> for date in rows_by_date:
...    print(date)
...    for row in rows_by_date[date]:
...        print('\t', row)07/01/2012{'address': '5412 N CLARK', 'date': '07/01/2012'}{'address': '4801 N BROADWAY', 'date': '07/01/2012'}
07/02/2012{'address': '5800 E 58TH', 'date': '07/02/2012'}{'address': '5645 N RAVENSWOOD', 'date': '07/02/2012'}{'address': '1060 W ADDISON', 'date': '07/02/2012'}
07/03/2012{'address': '2122 N CLARK', 'date': '07/03/2012'}
07/04/2012{'address': '5148 N CLARK', 'date': '07/04/2012'}{'address': '1039 W GRANVILLE', 'date': '07/04/2012'}

如果使用 collections.defaultdict 则不需要先对原始数据进行排序,因此如果内存允许那么使用这种方式则速度更快。

【Python 每日一技】根据序列中每个元素共同的数据域进行分组迭代相关推荐

  1. python内置函数返回序列中最大元素_Python之路(第八篇)Python内置函数、zip()、max()、min()...

    一.python内置函数 abs() 求绝对值 例子 print(abs(-2)) all() 把序列中每一个元素做布尔运算,如果全部都是true,就返回true, 但是如果是空字符串.空列表也返回t ...

  2. python内置函数返回序列中最大元素_Python 内置函数 ____________ 用来返回序列中的最大元素。_学小易找答案...

    [单选题]5. an official group of people who have joined together for a particular purpose [单选题]Excel 201 ...

  3. python内置函数用来返回数值型序列中所有元素之和_Python内置函数______用来返回数值型序列中所有元素之和...

    [填空题]表达式 int(4**0.5) 的值为 [判断题]3+4j不是合法的Python表达式. [填空题]已知列表对象x = ['11', '2', '3'],则表达式 max(x) 的值为 [填 ...

  4. python内置函数用来返回数值型序列中所有元素之和_语句x = 3==3, 5执行结束后,变量x的值为_学小易找答案...

    [判断题]不可以在同一台计算机上安装多个Python版本. [填空题]表达式[1, 2, 3]*3的执行结果为 [填空题]使用切片操作在列表对象x的开始处增加一个元素3的代码为 [填空题]Python ...

  5. python取列表前几个元素_Python下几种从一个序列中取出元素的方法

    使用Python进行数据处理时,有时候会有这样的操作,比如从一个列表或者numpy array中随机取出一个元素,对一个列表中的元素进行shuffle,等等.虽然这些操作也可以通过编写很简短的程序完成 ...

  6. python内置函数可以返回数值型序列中所有元素之和_Python内置函数________________用来返回数值型序列中所有元素之和。...

    [单选题]表达式 ','.join('a     b  ccc\n\n\nddd     '.split()) 的值为______________. [单选题]表达式 'abcabcabc'.coun ...

  7. python序列中各元素之间存在顺序关系_《Python Cookbook(第3版)中文版》——1.10 从序列中移除重复项且保持元素间顺序不变-阿里云开发者社区...

    本节书摘来自异步社区<Python Cookbook(第3版)中文版>一书中的第1章,第1.10节,作者[美]David Beazley , Brian K.Jones,陈舸 译,更多章节 ...

  8. python列表元素筛选_Python如何筛选序列中的元素

    本篇文章给大家带来的内容是关于Python如何筛选序列中的元素 ,有一定的参考价值,有需要的朋友可以参考一下,希望对你有所帮助. 1.需求 序列中含有一些数据,我们需要提取其中的值或根据某些标准对序列 ...

  9. python内置函数可以返回数值型序列中所有元素之和_智慧职教: Python内置函数________________用来返回数值型序列中所有元素之和。...

    智慧职教: Python内置函数________________用来返回数值型序列中所有元素之和. 答:3, 中国大学MOOC: 叙事性是插画的核心,每一幅插画背后都有一个作者心中的故事,或唯美,或悲 ...

最新文章

  1. linux文件系统逻辑,Linux系统——文件系统与LVM 逻辑
  2. Yii2与Yii1的模块中Layout使用区别
  3. Codeforces 358 D. Dima and Hares
  4. ext-4.2之grid的高级应用:增删改查!
  5. java api 英文_教你查阅Java API 英文文档(JDK 11)
  6. java eav_动态自定义字段属性–Magento的EAV模型 | 学步园
  7. java包裹邮费计算_GitHub - honghailiang/FreightSystem: 基于Java Swing编写的简易运费计算工具...
  8. android 布局属性
  9. kafka消息会不会丢失?为什么?看了这个你就清楚了
  10. java put方式提交_java – 通过HTTP PUT请求上传文件
  11. 双下巴的瘦脸运动方法 - 健康程序员,至尚生活!
  12. 从Github下载laravel项目遇到的坑
  13. MySQL数素数_素数是什么意思?
  14. java毕业设计springboot框架 java餐厅预约管理系统毕业设计开题报告功能参考
  15. 极限与连续知识点总结_知识点一(极限与连续).doc
  16. 跟我学AngularJs:AngularJs入门及第一个实例
  17. HDU 2036改革春风吹满地(有向面积的介绍)
  18. win10怎么取消开机磁盘检测
  19. android 苹果菜单栏,android仿iphone主题效果的主菜单
  20. 早报八点半:5月14日Web3行业隔夜新闻大汇总

热门文章

  1. 鹰潭高通量测序建设细节概述
  2. 如何查看域控计算机是哪个用户登陆,查看域控制器上登录用户
  3. 直播回顾 | 云原生混部系统 Koordinator 架构详解(附完整PPT)
  4. Vultr开启宝塔8888端口教程,手把手教你开启8888端口以及其它端口
  5. 数字电路的一些基本知识
  6. js 实现对象转字符串
  7. 健康指南:忙碌白领10种危险生活方式
  8. 携程移动端静态页面仿写
  9. 随机效应估算与固定效应估算_固定效应模型及估计原理说明.doc
  10. python——django连接html登陆界面