如何将列表中的相似项目分组?


问题内容

我想根据字符串中的前三个字符将类似的项目分组到一个列表中。例如:

test = ['abc_1_2', 'abc_2_2', 'hij_1_1', 'xyz_1_2', 'xyz_2_2']

如何根据第一个字母分组(例如'abc')将上述列表项分组?以下是预期的输出:

output = {1: ('abc_1_2', 'abc_2_2'), 2: ('hij_1_1',), 3: ('xyz_1_2', 'xyz_2_2')}

要么

output = [['abc_1_2', 'abc_2_2'], ['hij_1_1'], ['xyz_1_2', 'xyz_2_2']]

我尝试使用itertools.groupby来成功完成此任务:

>>> import os, itertools
>>> test = ['abc_1_2', 'abc_2_2', 'hij_1_1', 'xyz_1_2', 'xyz_2_2']
>>> [list(g) for k.split("_")[0], g in itertools.groupby(test)]
[['abc_1_2'], ['abc_2_2'], ['hij_1_1'], ['xyz_1_2'], ['xyz_2_2']]

我看过以下帖子,但没有成功:

如何合并列表中的类似项目。该示例使用对我的示例过于复杂的方法将相似的项(例如'house''Hose')分组。

如何在Python列表中将等效项分组在一起?。在这里,我找到了列表理解的想法。


问题答案:

.split("_")[0]零件应该在您作为第二个参数传递给的单参数函数内部itertools.groupby

>>> import os, itertools
>>> test = ['abc_1_2', 'abc_2_2', 'hij_1_1', 'xyz_1_2', 'xyz_2_2']
>>> [list(g) for _, g in itertools.groupby(test, lambda x: x.split('_')[0])]
[['abc_1_2', 'abc_2_2'], ['hij_1_1'], ['xyz_1_2', 'xyz_2_2']]
>>>

有它在for ...部分不做任何事情,因为结果被立即丢弃。


此外,str.partition如果您只希望进行单个拆分,则使用起来会更有效率:

[list(g) for _, g in itertools.groupby(test, lambda x: x.partition('_')[0])]

演示:

>>> from timeit import timeit
>>> timeit("'hij_1_1'.split('_')")
1.3149855638076913
>>> timeit("'hij_1_1'.partition('_')")
0.7576401470019234
>>>

这不是主要问题,因为这两种方法在小字符串上都非常快,但我想我会提到它。