按项目分组元组列表

Posted

技术标签:

【中文标题】按项目分组元组列表【英文标题】:Group list of tuples by item 【发布时间】:2016-09-22 22:58:05 【问题描述】:

我有这个列表作为例子:

[(148, Decimal('3.0')), (325, Decimal('3.0')), (148, Decimal('2.0')), (183, Decimal('1.0')), (308, Decimal('1.0')), (530, Decimal('1.0')), (594, Decimal('1.0')), (686, Decimal('1.0')), (756, Decimal('1.0')), (806, Decimal('1.0'))]

现在我想按 id 分组,所以我将使用itemgetter(0)

import operator, itertools
from decimal import *
test=[(148, Decimal('3.0')), (325, Decimal('3.0')), (148, Decimal('2.0')), (183, Decimal('1.0')), (308, Decimal('1.0')), (530, Decimal('1.0')), (594, Decimal('1.0')), (686, Decimal('1.0')), (756, Decimal('1.0')), (806, Decimal('1.0'))]

for _k, data in itertools.groupby(test, operator.itemgetter(0)):
    print list(data) 

我不知道为什么,但我得到了错误的输出:

[(148, Decimal('3.0'))]
[(325, Decimal('3.0'))]
[(148, Decimal('2.0'))]
[(183, Decimal('1.0'))]
[(308, Decimal('1.0'))]
[(530, Decimal('1.0'))]
[(594, Decimal('1.0'))]
[(686, Decimal('1.0'))]
[(756, Decimal('1.0'))]
[(806, Decimal('1.0'))]

如您所见,输出未按 id 分组。但是,如果我使用itemgetter(1),上面的代码可以正常工作。输出按十进制值分组。

[(148, Decimal('3.0')), (325, Decimal('3.0'))]
[(148, Decimal('2.0'))]
[(183, Decimal('1.0')), (308, Decimal('1.0')), (530, Decimal('1.0')), (594, Decimal('1.0')), (686, Decimal('1.0')), (756, Decimal('1.0')), (806, Decimal('1.0'))]

我在这里缺少什么?

【问题讨论】:

【参考方案1】:

您首先需要对数据进行排序,以便groupby 工作,它会根据您提供的键对连续元素 进行分组:

import operator, itertools
from decimal import *
test=[(148, Decimal('3.0')), (325, Decimal('3.0')), (148, Decimal('2.0')), (183, Decimal('1.0')), (308, Decimal('1.0')), (530, Decimal('1.0')), (594, Decimal('1.0')), (686, Decimal('1.0')), (756, Decimal('1.0')), (806, Decimal('1.0'))]

for _k, data in itertools.groupby(sorted(test), operator.itemgetter(0)):
    print list(data)

但您最好使用 dict 进行分组以避免不必要的 O(n log n) 排序:

from collections import defaultdict

d = defaultdict(list)

for t in test:
    d[t[0]].append(t)

for v in d.values():
    print(v)

两者都会给你相同的分组,只是不一定按照相同的顺序。

【讨论】:

【参考方案2】:

itertools.groupby()要求数据一致或排序。

[(148, Decimal('3.0')), (148, Decimal('2.0')), (325, Decimal('3.0'))] 可以工作,但[(148, Decimal('3.0')), (325, Decimal('3.0')), (148, Decimal('2.0'))] 不能工作,因为 id 是 148, 325, 148 而不是 148, 148, 325

【讨论】:

以上是关于按项目分组元组列表的主要内容,如果未能解决你的问题,请参考以下文章

如何将列表项分组为元组? [复制]

分组 Python 元组列表

python中的元组分组列表

如何对元组列表进行分组?

如何在 Spark Dataframe 上获取按结果分组的元组?

python数据结构之列表字典元组集合