使用 itertools groupby 创建列表列表

Using itertools groupby to create a list of lists

我正在获取 parent.id_child.id 格式的项目列表,例如 1_2。我尝试按 parent id 对 child 的 id 进行分组,例如: 从输入 ['1_2', '2_2', '1_1', '2_1', '1_3'] 我需要输出 [['1','2','3'], ['1','2']]。 我试过这个:

inputlist = ['1_2', '1_1', '2_1', '1_3', '2_2' ]
outputlist= [item.split('_') for item in inputlist]
outputlist.sort()
final = [list(group) for key, group in itertools.groupby(outputlist, lambda x: x[0])]

这对元素进行了正确的分组,因为我只需要获取每个项目的第二个元素。我怎样才能做到这一点?另外,我可以在一个列表理解句子中完成所有事情吗?

使用列表理解,是的;值本身被原样传递到每个组迭代器中,因此您需要再次 select:

final = [[g[1] for g in group] for key, group in itertools.groupby(outputlist, lambda x: x[0])]

您可以通过将拆分嵌套到 groupby 调用中,在单个表达式中完成整个操作,但这很快就会变得相当丑陋,即使拆分成多行也是如此:

final = [
    [g[1] for g in group]
    for key, group in itertools.groupby(
        sorted(item.split('_') for item in inputlist),
        lambda x: x[0])]

您可以避免对整个输入列表进行排序,而只对较小的组进行排序,方法是使用字典进行分组。根据您的 id 的大小,您可能还想对您的 id 进行 数字 排序(因为文本排序是按字典顺序完成的):

per_parent = {}
for item in inputlist:
    parent, child = item.split('_', 1)
    per_parent.setdefault(parent, []).append(child)
final = [children for parent, children in sorted(
    per_parent.items(), key=lambda pc: int(pc[0]))]

在Python2中,使用iteritems()而不是items()以避免构建中间列表。