如何对元组列表进行分组?
Posted
技术标签:
【中文标题】如何对元组列表进行分组?【英文标题】:How to group list of tuples? 【发布时间】:2018-05-31 12:30:54 【问题描述】:注意:我当然知道如何在显式 for 循环中执行此操作,但我正在寻找一种更具可读性的解决方案。
如果可能的话,我想通过使用一些内置功能来解决这个问题。最好的情况是这样的
result = [ *groupby logic* ]
假设如下列表:
import numpy as np
np.random.seed(42)
N = 10
my_tuples = list(zip(np.random.choice(list('ABC'), size=N),
np.random.choice(range(100), size=N)))
my_tuples
在哪里
[('C', 74),
('A', 74),
('C', 87),
('C', 99),
('A', 23),
('A', 2),
('C', 21),
('B', 52),
('C', 1),
('C', 87)]
如何使用来自 itertools 的 groupby
按标签 A、B 和 C 对索引(每个元组的索引 1 处的整数值)进行分组?
如果我这样做:
from itertools import groupby
#..
[(k,*v) for k, v in dict(groupby(my_tuples, lambda x: x[0])).items()]
我发现这会产生错误的结果。
期望的结果应该是
'A': [74, 23, 2],
# ..
【问题讨论】:
在下面你说你想要一个单行,但在这里你说你想要更多可读性。更少的行数并不一定意味着可读性更高,事实上,如果你尝试做太多事情,通常意味着可读性会大大降低。 作为提供itertools
答案的人,我完全同意@glibdud。可读性通常并不意味着单行化。 collections.defaultdict
的复杂度也较低。
@glibdud 好吧,我完全同意这里。但我保证我离开了我尝试编写“酷代码”的阶段:D
【参考方案1】:
最简单的解决方案可能是根本不使用groupby
。
from collections import defaultdict
d = defaultdict(list)
for k, v in my_tuples:
d[k].append(v)
我不使用groupby
的原因是groupby(iterable)
将iterable
中相邻的项目分组。因此,要将所有 'C'
值放在一起,您首先必须对列表进行排序。除非你有理由使用groupby
,否则没有必要。
【讨论】:
我实际上是希望找到一个“简单”的单行代码来保持代码更干净。我更喜欢我写result = [ *groupby* ]
的解决方案。
@StefanFalk 我建议您提到您希望结果在您的原始问题中成为单行,以便下次获得更好的答案。
这就是我专门询问groupby
的原因,但你是对的,我在寻找什么并不是很明显。【参考方案2】:
对于 O(n) 解决方案,您应该使用 collections.defaultdict
,请参阅 @PatrickHaugh's answer。
使用itertools.groupby
需要在分组前进行排序,产生O(n log n)复杂度:
from itertools import groupby
from operator import itemgetter
sorter = sorted(my_tuples, key=itemgetter(0))
grouper = groupby(sorter, key=itemgetter(0))
res = k: list(map(itemgetter(1), v)) for k, v in grouper
print(res)
'A': [74, 23, 2],
'B': [52],
'C': [74, 87, 99, 21, 1, 87]
【讨论】:
啊,现在我明白了.. +1 提醒我们时间复杂性。 不错。但是,这是 3 行。 不,我更喜欢你的 3 班轮。 OP 不喜欢帕特里克的解决方案,因为它不是一个单一的班轮并接受这一点。 @Attersson,是的,我同意你的观点,defaultdict
更好(我赞成)。但出于教育目的,有必要了解itertools.groupby
的工作原理。
@Attersson 你可以去掉 sorter
和 grouper
(不是说这看起来不错,但没有必要声明它们)。 jpp 也得到了它:我接受了他的回答,因为我在询问 groupby
,我认为人们最终可能会在这里寻找 groupby
的例子。以上是关于如何对元组列表进行分组?的主要内容,如果未能解决你的问题,请参考以下文章
如何在 Python 中对元组列表列表进行平面映射? [复制]