如果您希望在2.7(使用任意排序顺序)和3.x(拒绝对dicts排序)中使用与python2.x早期版本相同的行为,Ned Batchelder's answer to a question about how sorting dicts works可以部分实现,但不是全部。在
首先,它提供一个旧样式的cmp函数,而不是一个新样式的key函数。幸运的是,2.7和3.x都有^{}来解决这个问题。(当然,您可以将代码重写为键函数,但这可能会使您更难看到所发布代码与您的代码之间的任何差异…)
更重要的是,它不仅在2.7和3.x中做不到相同的事情,甚至在2.7和3.x中也不起作用def smallest_diff_key(A, B):
"""return the smallest key adiff in A such that A[adiff] != B[bdiff]"""
diff_keys = [k for k in A if A.get(k) != B.get(k)]
return min(diff_keys)
def dict_cmp(A, B):
if len(A) != len(B):
return cmp(len(A), len(B))
adiff = smallest_diff_key(A, B)
bdiff = smallest_diff_key(B, A)
if adiff != bdiff:
return cmp(adiff, bdiff)
return cmp(A[adiff], b[bdiff])
请注意,它正在对不匹配的值调用cmp。在
如果dicts可以包含其他dict,那么这取决于cmp(d1, d2)将最终调用这个函数……这在较新的Python中显然是不正确的。在
除此之外,在3.x中cmp甚至不再存在。在
另外,这依赖于这样一个事实:任何值都可以与任何其他值进行比较,您可能会得到任意结果,但不会得到异常。这在2.x中是正确的(少数情况除外),但在3.x中则不是这样。如果您不想将dict与不可比较的值进行比较(例如,{1: 2} < {1: 'b'}可以引发异常),那么这对您来说可能不是个问题,但在其他情况下,确实如此。在
当然,如果您不希望dict比较得到任意结果,那么您真的想要任意结果来进行值比较吗?在
这三个问题的解决方案很简单:必须替换cmp,而不是调用它。所以,像这样:
^{pr2}$
如果您需要2.7使用的不同类型对象的精确比较规则,they're documented,那么您可以实现它们。但是如果您不需要太多细节,可以在这里编写一些更简单的代码(或者甚至可以不捕获TypeError,如果上面提到的异常可以接受的话)。在