【问题标题】:Python compare-sort only compares neighborsPython比较排序只比较邻居
【发布时间】:2014-01-16 18:02:12
【问题描述】:

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

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

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

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>

差不多。

【问题讨论】:

    标签: python sorting compare


    【解决方案1】:

    不要使用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>
    

    当将任何fancy SortMe 对象与boring 对象进行比较时,您的cmp 键方法仍会返回0,无论它们的顺序如何,都会产生不一致的排序。在比较两个类型不同的对象时,您需要始终返回 -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>
    

    【讨论】:

    • 是的。堆栈溢出 FTW!谢谢。
    猜你喜欢
    • 1970-01-01
    • 2019-10-05
    • 2010-09-20
    • 2013-08-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多