Python 使用itertools.groupby导入输出

Python 使用itertools.groupby导入输出,python,group-by,itertools,Python,Group By,Itertools,我得到了这个家庭作业问题,在上完Udemy课程后,我仍然不知道如何获得正确的输出,比如解决方案 此外:我怎样才能使它更有效率。如果不使用显式循环,而是使用列表/字典理解,我怎么做呢 我就是这么做的: def group_permutation_values(permutations_list): dic = {} f = lambda x: x[1] for key, group in itertools.groupby(sorted(permutations_lis

我得到了这个家庭作业问题,在上完Udemy课程后,我仍然不知道如何获得正确的输出,比如解决方案

此外:我怎样才能使它更有效率。如果不使用显式循环,而是使用列表/字典理解,我怎么做呢

我就是这么做的:

def group_permutation_values(permutations_list): 

    dic = {}
    f = lambda x: x[1]
    for key, group in itertools.groupby(sorted(permutations_list, key=f), f):
        dic[key] = list(group)

    return dic

    pass

results = [
    ((1, 2, 3), -4),
    ((1, 3, 2), -4),
    ((2, 1, 3), -2),
    ((2, 3, 1), -2),
    ((3, 1, 2), 0), 
    ((3, 2, 1), 0)
]
print(group_permutation_values(results))
这就是我得到的:

{
    -4: [((1, 2, 3), -4), ((1, 3, 2), -4)],
    -2: [((2, 1, 3), -2), ((2, 3, 1), -2)],
     0: [((3, 1, 2), 0), ((3, 2, 1), 0)]
}
以及预期产出:

{
    -4: [(1, 2, 3), (1, 3, 2)],
    -2: [(2, 1, 3), (2, 3, 1)],
     0: [(3, 1, 2), (3, 2, 1)]
}

groupby
的键函数仅确定值的分组方式;该函数不用于更改组元素本身。仅仅因为您按
元素[1]
进行分组,并不意味着这些组将只包含
元素[0]
,您就得到了整个元组

创建列表值时,只需从组的每个元素中提取第一个嵌套元组:

dic[key] = [t[0] for t in group]
因此,当
列表(组)
返回
[(1,2,3),-4),((1,3,2),-4)]
时,上述列表理解反而产生
[(1,2,3),(1,3,2)]

您可以将外部
for
循环从
groupby
结果构建字典替换为字典理解:

def group_permutation_values(permutations_list): 
    f = lambda x: x[1]
    sorted_list = sorted(permutations_list, key=f)
    return {k: [t[0] for t in g] for k, g in itertools.groupby(sorted_list, f)}
然而,在这里使用
groupby()
是错误的工具
groupby()
要求首先对输入进行排序,这会降低性能。排序是一个O(N log N)操作,但将元组放入字典可以在O(N)线性时间内完成,只需在输入列表上循环并在每个条目的列表上追加:

def group_permutation_values(permutations_list):
    grouped = {}
    for a, b in permutations_list:
        grouped.setdefault(b, []).append(a)
    return grouped

这不能转化为一个字典理解,但更有效的是,尽管如此。理解不是灵丹妙药,它们只是一种语法,通过处理iterable中的每个元素来创建容器(列表、词典、集合)。是的,对于添加到容器操作的-loop,它们比等价的
更有效,但是它们仍然受到通常算法时间复杂性的影响。

请不要通过破坏您的帖子为其他人做更多的工作。通过在Stack Exchange网络上发布,您已授予Stack Exchange在下不可撤销的权利,以分发该内容(即,无论您未来的选择如何)。根据堆栈交换策略,帖子的非破坏版本是分发的版本。因此,任何故意破坏行为都将恢复原状。如果您想了解有关删除帖子的更多信息,请参阅: