以下列表包含格式(ID,级别,值):
[(A, 1, None),
(B, 1, None),
(C, 1, None),
(A, 2, 1.1),
(B, 2, 5.0),
(C, 2, 5.0),
(C, 3, 40),
(B, 3, 55)]
因此,问题是根据来自一个级别更低的值,使用相同的值对具有相同级别的项目进行排序。如果下面的一个级别的值相等,则它会低于2级,依此类推。所以结束列表应如下所示:
[(A, 1, None),
(C, 1, None), <- this moved up because @ lvl3 C['value'] < B['value']
(B, 1, None),
(A, 2, 1.1),
(C, 2, 5.0), <- this moved up because @ lvl3 C['value'] < B['value']
(B, 2, 5.0),
(C, 3, 40),
(B, 3, 55),]
有人可以建议一种算法来实现吗?顺便说一句,我总是得到按值排序的起始列表,然后是 level
答案 0 :(得分:5)
您需要一个查找表来确定每个(ID, level)
元组的值。您需要将所有可能的级别查找添加到排序键:
# Lookup for values by (id, level)
values = {}
minlevel, maxlevel = float('inf'), float('-inf')
for id_, level, value in inputlist:
values[id_, level] = value
if level < minlevel:
minlevel = level
if level > maxlevel:
maxlevel = level
def level_sort(tup):
id_, level, value = tup
sortkey = [level]
for l in range(minlevel, maxlevel + 1):
sortkey.append(values.get((id_, l)) if l >= level else None)
return sortkey
sorted(inputlist, key=level_sort)
sort函数生成要排序的值列表,从它们自己级别的值开始(对于任何较低级别填充None
)加上较高级别的相同ID的值。
例如,对于(B, 1, None)
和(C, 1, None)
元组,sort函数输出:
>>> level_sort(('B', 1, None))
[1, None, 5.0, 55]
>>> level_sort(('C', 1, None))
[1, None, 5.0, 40]
其中只有最后一个值不同并确定最终的排序顺序。
为此,您需要首先了解输入列表中的最小和最大级别,因此需要更精细的地图构建循环。
演示:
>>> from pprint import pprint
>>> A, B, C = 'ABC'
>>> inputlist = [(A, 1, None),
... (B, 1, None),
... (C, 1, None),
... (A, 2, 1.1),
... (B, 2, 5.0),
... (C, 2, 5.0),
... (C, 3, 40),
... (B, 3, 55)]
>>> values = {}
>>> minlevel, maxlevel = float('inf'), float('-inf')
>>> for id_, level, value in inputlist:
... values[id_, level] = value
... if level < minlevel:
... minlevel = level
... if level > maxlevel:
... maxlevel = level
...
>>> def level_sort(tup):
... id_, level, value = tup
... sortkey = [level]
... for l in range(minlevel, maxlevel + 1):
... sortkey.append(values.get((id_, l)) if l >= level else None)
... return sortkey
...
>>> pprint(sorted(inputlist, key=level_sort))
[('A', 1, None),
('C', 1, None),
('B', 1, None),
('A', 2, 1.1),
('C', 2, 5.0),
('B', 2, 5.0),
('C', 3, 40),
('B', 3, 55)]