Python Itertools groupby使用lambda函数,将列表的子列表分组在一起(如果它们在索引0和1处具有匹配值)
我有这样一个列表:Python Itertools groupby使用lambda函数,将列表的子列表分组在一起(如果它们在索引0和1处具有匹配值),python,performance,group-by,itertools,Python,Performance,Group By,Itertools,我有这样一个列表: data = [['a', 'b', 2000, 100], ['a', 'b', 4000, 500], ['c', 'd', 500, 8000], ['c', 'd', 60, 8000], ['c', 'd', 70, 1000], ['a', 'd', 2000, 100], ['a', 'd', 1000, 100]] 如果前两个值相同,我想把它们组合在一起。产出将是: data = [(['a', 'b', 2000, 100], ['a', 'b', 400
data = [['a', 'b', 2000, 100], ['a', 'b', 4000, 500], ['c', 'd', 500, 8000], ['c', 'd', 60, 8000], ['c', 'd', 70, 1000], ['a', 'd', 2000, 100], ['a', 'd', 1000, 100]]
如果前两个值相同,我想把它们组合在一起。产出将是:
data = [(['a', 'b', 2000, 100], ['a', 'b', 4000, 500]), (['c', 'd', 500, 8000], ['c', 'd', 60, 8000], ['c', 'd', 70, 1000]), (['a', 'd', 2000, 100], ['a', 'd', 1000, 100])]
具有相同前两个值的子列表在列表中总是彼此相邻,但它们在我需要分组的数量上有所不同
我试过这个:
from itertools import groupby
data = [['a', 'b', 2000, 100], ['a', 'b', 4000, 500], ['c', 'd', 500, 8000], ['c', 'd', 60, 8000], ['c', 'd', 70, 1000], ['a', 'd', 2000, 100], ['a', 'd', 1000, 100]]
output = [list(group) for key, group in groupby(data, lambda x:x[0])]
new_data = []
for l in output:
new_output = [tuple(group) for key, group in groupby(l, lambda x:x[1])]
for grouped_sub in new_output:
new_data.append(grouped_sub)
print(new_data)
并得到了输出:
[(['a', 'b', 2000, 100], ['a', 'b', 4000, 500]), (['c', 'd', 500, 8000], ['c', 'd', 60, 8000], ['c', 'd', 70, 1000]), (['a', 'd', 2000, 100], ['a', 'd', 1000, 100])]
[(['a', 'b', 2000, 100], ['a', 'b', 4000, 500]), (['c', 'd', 500, 8000], ['c', 'd', 60, 8000], ['c', 'd', 70, 1000]), (['a', 'd', 2000, 100], ['a', 'd', 1000, 100])]
这正是我想要的。但是,我的列表列表是<代码> LeN(data)=1000000 < /代码>,我知道如果我可以完全跳过for循环,并且在某种程度上得到<代码> GROPbB/<代码>代码> LAMBDA < /Cord>,在分组时考虑<代码> x [0 ] < /代码>和<代码> x(1)< /代码>。但是我还不太明白
groupby
中的lambda
函数是如何工作的 修改键lambda以返回包含两个元素的元组:
groupby(data, lambda x: tuple(x[0:2]))
i、 e.可以在单个循环/列表中完成:
>>> [tuple(group) for key, group in groupby(data, lambda x: tuple(x[0:2]))]
[(['a', 'b', 2000, 100], ['a', 'b', 4000, 500]),
(['c', 'd', 500, 8000], ['c', 'd', 60, 8000], ['c', 'd', 70, 1000]),
(['a', 'd', 2000, 100], ['a', 'd', 1000, 100])]
修改键lambda以返回包含两个元素的元组:
groupby(data, lambda x: tuple(x[0:2]))
i、 e.可以在单个循环/列表中完成:
>>> [tuple(group) for key, group in groupby(data, lambda x: tuple(x[0:2]))]
[(['a', 'b', 2000, 100], ['a', 'b', 4000, 500]),
(['c', 'd', 500, 8000], ['c', 'd', 60, 8000], ['c', 'd', 70, 1000]),
(['a', 'd', 2000, 100], ['a', 'd', 1000, 100])]
为什么不直接按前两项分组:
from itertools import groupby
data = [['a', 'b', 2000, 100], ['a', 'b', 4000, 500], ['c', 'd', 500, 8000], ['c', 'd', 60, 8000], ['c', 'd', 70, 1000], ['a', 'd', 2000, 100], ['a', 'd', 1000, 100]]
res = [tuple(g) for k, g in groupby(data, key=lambda x: x[:2])]
print(res)
输出:
[(['a', 'b', 2000, 100], ['a', 'b', 4000, 500]), (['c', 'd', 500, 8000], ['c', 'd', 60, 8000], ['c', 'd', 70, 1000]), (['a', 'd', 2000, 100], ['a', 'd', 1000, 100])]
[(['a', 'b', 2000, 100], ['a', 'b', 4000, 500]), (['c', 'd', 500, 8000], ['c', 'd', 60, 8000], ['c', 'd', 70, 1000]), (['a', 'd', 2000, 100], ['a', 'd', 1000, 100])]
为什么不直接按前两项分组:
from itertools import groupby
data = [['a', 'b', 2000, 100], ['a', 'b', 4000, 500], ['c', 'd', 500, 8000], ['c', 'd', 60, 8000], ['c', 'd', 70, 1000], ['a', 'd', 2000, 100], ['a', 'd', 1000, 100]]
res = [tuple(g) for k, g in groupby(data, key=lambda x: x[:2])]
print(res)
输出:
[(['a', 'b', 2000, 100], ['a', 'b', 4000, 500]), (['c', 'd', 500, 8000], ['c', 'd', 60, 8000], ['c', 'd', 70, 1000]), (['a', 'd', 2000, 100], ['a', 'd', 1000, 100])]
[(['a', 'b', 2000, 100], ['a', 'b', 4000, 500]), (['c', 'd', 500, 8000], ['c', 'd', 60, 8000], ['c', 'd', 70, 1000]), (['a', 'd', 2000, 100], ['a', 'd', 1000, 100])]
@itay我需要保留在
csv
模块中,因为我将在pandas
中迭代组和列不是一个好的做法。@itay我需要保留在csv
模块中,因为我将在pandas
中迭代组和列不是一个好的做法练习。@AnnaNevison,默认情况下,带slicex[:2]
-0
的片段被暗示为起始索引。顺便说一句,我的方法不会强制转换到tupletuple(…)
twice@AnnaNevison默认情况下,带切片的x[:2]
-0
被暗示为起始索引。顺便说一句,我的方法不会对tupletuple(…)
twice进行强制转换谢谢!!这是正确的,您和另一个答案同时用相同的东西进行了注释,但我将接受另一个答案,因为它包含完整的代码,您不需要从0开始切片。(还有,你的有5张赞成票,所以如果我接受他的话,他得到的分数几乎和你一样多)。但是我非常感谢你的帮助!谢谢大家!@安纳尼森,你很有公平感和理性主义。我很少在这里看到这种情况。)好的,谢谢你!!这是正确的,您和另一个答案同时用相同的东西进行了注释,但我将接受另一个答案,因为它包含完整的代码,您不需要从0开始切片。(还有,你的有5张赞成票,所以如果我接受他的话,他得到的分数几乎和你一样多)。但是我非常感谢你的帮助!谢谢大家!@安纳尼森,你很有公平感和理性主义。我很少在这里看到这种情况。)好的