Itertools Groupby提供了意外结果

问题描述

我有两个列表

finalblobfpost1=['ABC/XYZ/16082020/K1_SS_ALM_222222_14082020.txt','ABC/XYZ/16082020/K1_SS_ALM_111111_14082020.txt','ABC/XYZ/15082020/K1_AB_KIL_444444_15082020.txt','ABC/XYZ/15082020/K1_AB_KIL_333333_15082020.txt']

“ K1_SS_ALM”的日期相同

finalblobfpost2=['ABC/XYZ/15082020/K1_SS_ALM_222222_15082020.txt','ABC/XYZ/16082020/K1_SS_ALM_111111_16082020.txt','ABC/XYZ/16082020/K1_AB_KIL_333333_16082020.txt']

使用与“ K1_SS_ALM”不同的日期

我需要使用K1_SS_ALM和K1_AB_KIL分组(re.findall(“ \ w + / \ w + / \ d + /(。*?)_ \ d + _ \ d + .txt”,文本))

到目前为止的Mycode:

finalblobfpost1=['ABC/XYZ/16082020/K1_SS_ALM_222222_14082020.txt','ABC/XYZ/15082020/K1_AB_KIL_333333_15082020.txt']
keyf = lambda text: (re.findall("\w+\/\w+\/\d+\/(.*?)\_\d+_\d+.txt",text)+ [text])[0].strip()
h=[list(items) for gr,items in groupby(sorted(finalblobfpost1),key=keyf)]
print(h)

结果令人满意-

[['ABC/XYZ/15082020/K1_AB_KIL_333333_15082020.txt','ABC/XYZ/15082020/K1_AB_KIL_444444_15082020.txt'],['ABC/XYZ/16082020/K1_SS_ALM_111111_14082020.txt','ABC/XYZ/16082020/K1_SS_ALM_222222_14082020.txt']]

代码:2

finalblobfpost2=['ABC/XYZ/15082020/K1_SS_ALM_222222_15082020.txt','ABC/XYZ/16082020/K1_AB_KIL_333333_16082020.txt']
keyf1 = lambda text: (re.findall("\w+\/\w+\/\d+\/(.*?)\_\d+_\d+.txt",text)+ [text])[0].strip()
h1=[list(items) for gr,items in groupby(sorted(finalblobfpost2),key=keyf1)]
print(h1)

结果是:不期望

[['ABC/XYZ/15082020/K1_AB_KIL_444444_15082020.txt'],['ABC/XYZ/15082020/K1_SS_ALM_222222_15082020.txt'],['ABC/XYZ/16082020/K1_AB_KIL_333333_16082020.txt'],['ABC/XYZ/16082020/K1_SS_ALM_111111_16082020.txt']]

预期是:

[['ABC/XYZ/15082020/K1_AB_KIL_444444_15082020.txt','ABC/XYZ/16082020/K1_AB_KIL_333333_16082020.txt'],['ABC/XYZ/16082020/K1_SS_ALM_111111_16082020.txt','ABC/XYZ/15082020/K1_AB_KIL_444444_15082020.txt']]

它没有对关键字进行分组。正则表达式有什么问题吗,或者我做错了什么?

请告知。

解决方法

您的列表需要使用与groupby中相同的键功能进行排序!

尝试一下:

h1=[list(items) for gr,items in groupby(sorted(finalblobfpost2,key=keyf1),key=keyf1)]

唯一的区别是调用的key=keyf1

输出(与预期相同):

[['ABC/XYZ/15082020/K1_AB_KIL_444444_15082020.txt','ABC/XYZ/16082020/K1_AB_KIL_333333_16082020.txt'],['ABC/XYZ/15082020/K1_SS_ALM_222222_15082020.txt','ABC/XYZ/16082020/K1_SS_ALM_111111_16082020.txt']]

这明确地写在docs for groupby中:

groupby()的操作类似于Unix中的uniq过滤器。它 每次键值产生一个中断或新组 功能更改(这就是为什么通常需要进行排序的原因 数据使用相同的按键功能)。

,

尝试一下

Regex Demo

import re
from itertools import groupby

print(
    [list(v) for _,v in groupby(finalblobfpost1,key=lambda x: re.search("\w\d+_\w{2}_\w{3}",x).group())]
)

[['ABC/XYZ/16082020/K1_SS_ALM_222222_14082020.txt','ABC/XYZ/16082020/K1_SS_ALM_111111_14082020.txt'],['ABC/XYZ/15082020/K1_AB_KIL_444444_15082020.txt','ABC/XYZ/15082020/K1_AB_KIL_333333_15082020.txt']]