Python高级列表排序

and*_*d3p 0 python sorting list

以下列表具有格式(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)]
Run Code Online (Sandbox Code Playgroud)

因此,捕获的是根据它们的值从较低的一个级别对具有相同的相同级别的项目进行排序.如果下面一个级别的值相等,则它会低于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),]
Run Code Online (Sandbox Code Playgroud)

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

Mar*_*ers 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)
Run Code Online (Sandbox Code Playgroud)

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]
Run Code Online (Sandbox Code Playgroud)

只有最后一个值不同并确定最终排序顺序.

为此,您需要首先了解输入列表中的最小和最大级别,因此需要更精细的地图构建循环.

演示:

>>> 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)]
Run Code Online (Sandbox Code Playgroud)