Python比较排序仅比较邻居

时间:2014-01-16 18:02:12

标签: python sorting compare

以下代码对对象列表进行排序。

我想要实现的是按其值对“无聊”类型的对象进行排序。我不关心他们在列表中的位置,但最后他们需要进行排序。我的代码只比较邻居,因此最终仍然是错误的顺序。

需要应用哪种类型的排序算法才能正确排序?

class SortMe:
    def __init__(self, type, value):
        self.type = type
        self.value = value
    def __repr__(self):
        return "<%s %s %s>" % (self.__class__.__name__, self.type, self.value)

stack = (
    SortMe('fancy', 15),
    SortMe('fancy', 3),
    SortMe('boring', 3),
    SortMe('boring', 1),
    SortMe('fancy', 1),
    SortMe('boring', 22),
    SortMe('fancy', 22),
    SortMe('fancy', 17),
    SortMe('boring', 5),
    )

def compare(a1, a2):
    if a1.type == 'boring' and a2.type == 'boring':
        if a1.value > a2.value:
            return 1
        elif a1.value < a2.value:
            return -1
        else:
            return 0
    else:
        return 0

stack = sorted(stack, cmp=compare)

print '\n'.join(map(str, stack))

当前输出(钻孔对象的顺序错误):

<SortMe fancy 15>
<SortMe fancy 3>
<SortMe boring 1>
<SortMe boring 3>
<SortMe fancy 1>
<SortMe boring 22>
<SortMe fancy 22>
<SortMe fancy 17>
<SortMe boring 5>

预期输出(顺序无聊,位置无关紧要):

<SortMe fancy 15>
<SortMe fancy 3>
<SortMe boring 1>
<SortMe boring 3>
<SortMe fancy 1>
<SortMe boring 5>
<SortMe boring 22>
<SortMe fancy 22>
<SortMe fancy 17>

或:

<SortMe fancy 15>
<SortMe fancy 3>
<SortMe fancy 1>
<SortMe fancy 22>
<SortMe fancy 17>
<SortMe boring 1>
<SortMe boring 3>
<SortMe boring 5>
<SortMe boring 22>

左右。

1 个答案:

答案 0 :(得分:0)

不要使用cmp密钥,只需使用key函数直接提取值:

sorted(stack, key=lambda v: v.value if v.type == 'boring' else None)

产生:

>>> for sm in sorted(stack, key=lambda v: v.value if v.type == 'boring' else None):
...     print sm
... 
<SortMe fancy 15>
<SortMe fancy 3>
<SortMe fancy 1>
<SortMe fancy 22>
<SortMe fancy 17>
<SortMe boring 1>
<SortMe boring 3>
<SortMe boring 5>
<SortMe boring 22>

在将cmp 0个对象与fancy个对象进行比较时,SortMe密钥方法仍然会返回boring,无论它们处于何种顺序,都会创建一个排序不一致。在比较两个类型不同的对象时,您需要始终返回-11

def compare(a1, a2):
    if a1.type == 'boring' and a2.type == 'boring':
        return cmp(a1.value, a2.value)
    else:
        # sort fancy before boring, reverse order
        return cmp(a2.type, a1.type)

我重复使用cmp()内置函数返回相应的-101值:

>>> def compare(a1, a2):
...     if a1.type == 'boring' and a2.type == 'boring':
...         return cmp(a1.value, a2.value)
...     else:
...         return cmp(a2.type, a1.type)
... 
>>> for sm in sorted(stack, compare):
...     print sm
... 
<SortMe fancy 15>
<SortMe fancy 3>
<SortMe fancy 1>
<SortMe fancy 22>
<SortMe fancy 17>
<SortMe boring 1>
<SortMe boring 3>
<SortMe boring 5>
<SortMe boring 22>
相关问题