以下代码对对象列表进行排序。
我想要实现的是按其值对“无聊”类型的对象进行排序。我不关心他们在列表中的位置,但最后他们需要进行排序。我的代码只比较邻居,因此最终仍然是错误的顺序。
需要应用哪种类型的排序算法才能正确排序?
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>
左右。
答案 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
,无论它们处于何种顺序,都会创建一个排序不一致。在比较两个类型不同的对象时,您需要始终返回-1
或1
:
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()
内置函数返回相应的-1
,0
或1
值:
>>> 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>