Python的理解可以组成团队吗?

时间:2014-04-30 11:44:44

标签: python collections group-by aggregate list-comprehension

我有一个类似于

的列表
[(1,2,5),(2,10,13),(5,24,56),(1,8,10),(2,3,11)]

如何通过按元组的第一个元素分组并在第二个元素中查找min元素和在第三个元素中查找max元素来生成字典:

{1:(2,10),2:(3,13),5:{24,56}]

2 个答案:

答案 0 :(得分:6)

如果您首先在分组元素上排序,则可以使用itertools.groupby()对元素进行分组并测试最小值和最大值。由于这些组是生成器,因此您需要跳过一个额外的环,将其转换为可以为min()max()函数重用的列表:

from itertools import groupby
from operator import itemgetter

result = {k: (min(item[1] for item in gv), max(item[2] for item in gv))
         for k, g in groupby(sorted(inputlist, key=itemgetter(0)), itemgetter(0))
         for gv in (list(g),)}

请注意,此排序(O(NlogN))然后循环遍历每个组两次,以查找每个组的最小值和最大值,并为总数添加另外2N。

其他for gv in (list(g),)循环会将一个列表分配给gv,其中包含g组中的所有元素。

简单循环版本将是:

result = {}
for key, v1, v2 in inputlist:
    minimum, maximum = result.get(key, (float('inf'), float('-inf')))
    if v1 < minimum:
        minimum = v1
    if v2 > maximum:
        maximum = v2
    result[key] = (minimum, maximum)

这是一个简单的O(N)循环,更具可读性。

演示两种方法:

>>> from itertools import groupby
>>> from operator import itemgetter
>>> inputlist = [(1,2,5),(2,10,13),(5,24,56),(1,8,10),(2,3,11)]
>>> {k: (min(item[1] for item in gv), max(item[2] for item in gv))
...          for k, g in groupby(sorted(inputlist, key=itemgetter(0)), itemgetter(0))
...          for gv in (list(g),)}
{1: (2, 10), 2: (3, 13), 5: (24, 56)}

>>> result = {}
>>> for key, v1, v2 in inputlist:
...     minimum, maximum = result.get(key, (float('inf'), float('-inf')))
...     if v1 < minimum:
...         minimum = v1
...     if v2 > maximum:
...         maximum = v2
...     result[key] = (minimum, maximum)
... 
>>> result
{1: (2, 10), 2: (3, 13), 5: (24, 56)}

答案 1 :(得分:0)

In [9]: ll = [(1,2,5),(2,10,13),(5,24,56),(1,8,10),(2,3,11)]

In [10]: {k[0]: ( min([kk[1] for kk in ll if kk[0] == k[0]]), max([kk[2] for kk in ll if kk[0] == k[0]]) ) for k in ll}
Out[10]: {1: (2, 10), 2: (3, 13), 5: (24, 56)}

In [11]: {k[0]: (v[0], v[-1]) for k in ll for v in [sorted([x for y in [[kk[1], kk[2]] for kk in ll if kk[0] == k[0] ] for  x in y])] }
Out[11]: {1: (2, 10), 2: (3, 13), 5: (24, 56)}