我有一个类似于
的列表[(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}]
答案 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)}