0

以下列表具有格式(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)]

因此,问题是根据较低级别的值对具有相同值的同一级别的项目进行排序。如果低于一级的值相等,则低于二级,依此类推。所以最终列表应该是这样的:

[(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),]

有人可以建议一种算法来实现这一目标吗?顺便说一句,我总是得到按排序的起始列表,然后按级别排序

4

1 回答 1

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)元组,排序函数输出:

>>> 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)]
于 2013-10-04T11:33:39.537 回答