我没有't been able to find an understandable explanation of how to actually use Python' s itertools.groupby()
功能 . 我想要做的是:
-
拿一个清单 - 在这种情况下,是一个物化的
lxml
元素的子项 -
根据某些标准将其分组
-
然后分别迭代这些组中的每一个 .
我已经审核了the documentation和the examples,但我在尝试将它们应用到一个简单的数字列表之外时遇到了麻烦 .
那么,我如何使用 itertools.groupby()
?我应该使用另一种技术吗?阅读良好的指针也将受到赞赏 .
12 回答
IMPORTANT NOTE: 你必须先 sort your data .
我没有得到的部分是在示例构造中
k
是当前分组键,g
是一个迭代器,可用于迭代该分组键定义的组 . 换句话说,groupby
迭代器本身返回迭代器 .这是一个例子,使用更清晰的变量名称:
这会给你输出:
在此示例中,
things
是元组列表,其中每个元组中的第一个项目是第二个项目所属的组 .groupby()
函数有两个参数:(1)要分组的数据和(2)将其分组的函数 .这里,
lambda x: x[0]
告诉groupby()
使用每个元组中的第一项作为分组键 .在上面的
for
语句中,groupby
返回三个(键,组迭代器)对 - 每个唯一键一次 . 您可以使用返回的迭代器迭代该组中的每个项目 .以下是使用列表推导的相同数据的略有不同的示例:
这会给你输出:
你能告诉我们你的代码吗?
Python文档中的示例非常简单:
因此,在您的情况下,数据是节点列表,keyfunc是条件函数的逻辑所在的位置,然后
groupby()
对数据进行分组 .在调用
groupby
之前,您必须小心 sort the data ,否则它将无效 .groupby
方法实际上只是迭代一个列表,每当密钥更改它创建一个新组 .使用groupby的neato技巧是在一行中运行长度编码:
将给出一个2元组的列表,其中第一个元素是char,第二个元素是重复的数量 .
编辑:请注意,这是将
itertools.groupby
与SQLGROUP BY
语义分开的内容:itertools不会预先对迭代器进行排序,因此不会合并具有相同"key"的组 .itertools.groupby
是一个用于分组项目的工具 .从the docs开始,我们会进一步收集它可能做的事情:
groupby
对象产生组组为生成器的键组对 .特征
A.将连续项目组合在一起
B.给定一个已排序的可迭代项,对所有出现的项进行分组
C.指定如何使用键功能对项目进行分组
比较
用途
Anagrams(see notebook)
Binning
Group odd and even numbers
Group a list by values
Remove duplicate elements
Find indices of repeated elements in an array
Split an array into n-sized chunks
Find corresponding elements between two lists
Compression algorithm(see notebook)/ Run Length Encoding
Grouping letters by length, key function(see notebook)
Consecutive values over a threshold(see notebook)
Find ranges of numbers in a list或continuous items(见docs)
Find all related longest sequences
Take consecutive sequences that meet a condition(see related post)
注意:后面的几个例子来自VíctorTerrón的PyCon (talk) (Spanish),"Kung Fu at Dawn with Itertools" . 另见用C编写的
groupby
source code .响应
另一个例子:
结果是
请注意,igroup是一个迭代器(文档调用它的子迭代器) .
这对于分块生成器很有用:
groupby的另一个例子 - 当键没有排序时 . 在以下示例中,xx中的项目按yy中的值进行分组 . 在这种情况下,首先输出一组零,然后输出一组1,然后再输出一组零 .
生产环境 :
警告:
语法列表(groupby(...))将无法按您的意图运行 . 它似乎破坏了内部迭代器对象,所以使用
将产生:
相反,列表(groupby(...)),尝试[(k,list(g))for k,g in groupby(...)],或者如果经常使用该语法,
并且可以访问groupby功能,同时避免那些讨厌的(对于小数据)迭代器 .
我想举一个例子,其中没有排序的groupby不起作用 . 改编自James Sulak的例子
输出是
有两个车辆组,而一个人只能期待一组
@CaptSolo,我试过你的例子,但它没有用 .
输出:
尽你所能看,有两个和两个e,但他们分成了不同的组 . 那时我意识到你需要对传递给groupby函数的列表进行排序 . 所以,正确的用法是:
输出:
只记得,如果列表没有排序,groupby函数 will not work !
您可以使用groupby将事物分组以进行迭代 . 你给groupby一个iterable,并给一个可选的 key 函数/ callable来检查它们从iterable出来时的项目,然后它返回一个迭代器,给出一个两元组的key可调用的结果和实际的item另一个可迭代的 . 从帮助:
下面是groupby使用协程按计数分组的示例,它使用密钥可调用(在本例中为
coroutine.send
)来为多次迭代和元素的分组子迭代器吐出计数:版画
我遇到的一个有用的例子可能会有所帮助:
样本输入:14445221
样本输出:(1,1)(3,4)(1,5)(2,2)(1,1)
你可以编写自己的groupby函数: