IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Python知识库 -> 【Python 每日一技】根据序列中每个元素共同的数据域进行分组迭代 -> 正文阅读

[Python知识库]【Python 每日一技】根据序列中每个元素共同的数据域进行分组迭代

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知识库 最新文章
Python中String模块
【Python】 14-CVS文件操作
python的panda库读写文件
使用Nordic的nrf52840实现蓝牙DFU过程
【Python学习记录】numpy数组用法整理
Python学习笔记
python字符串和列表
python如何从txt文件中解析出有效的数据
Python编程从入门到实践自学/3.1-3.2
python变量
上一篇文章      下一篇文章      查看所有文章
加:2022-03-22 20:32:46  更:2022-03-22 20:32:51 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/15 19:39:52-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码