如何检查对象在 Python 中是否可排序/可排序?
我正在尝试为__init__
我的二叉树类的方法实现基本类型检查,并且我希望能够检查节点的值是否可排序,如果不是则抛出错误。它类似于在哈希表的实现中检查哈希性。
我正在尝试完成类似于 Haskell 的(Ord a) => etc.
预选赛的事情。Python中有类似的检查吗?
如何检查对象在 Python 中是否可排序/可排序?
我正在尝试为__init__
我的二叉树类的方法实现基本类型检查,并且我希望能够检查节点的值是否可排序,如果不是则抛出错误。它类似于在哈希表的实现中检查哈希性。
我正在尝试完成类似于 Haskell 的(Ord a) => etc.
预选赛的事情。Python中有类似的检查吗?
如果你想知道一个对象是否可排序,你必须检查它是否实现了必要的比较方法。
在Python 2.X中有两种不同的方式来实现这些方法:
cmp 方法(每个示例相当于 Java 中的 compareTo)
__cmp__(self, other)
: 返回 >0、0 或 <0 自我是否大于、等于或小于其他
丰富的比较方法
__lt__, __gt__, __eq__, __le__, __ge__, __ne__
sort() 函数调用该方法在实例之间进行必要的比较(实际上 sort 只需要__lt__
or__gt__
方法,但建议全部实现)
在Python 3.X中__cmp__
,删除了有利于丰富的比较方法,因为有不止一种方法来做同样的事情确实违反了 Python 的“法律”。
因此,您基本上需要一个函数来检查这些方法是否由类实现:
# Python 2.X
def is_sortable(obj):
return hasattr(obj, "__cmp__") or \
hasattr(obj, "__lt__") or \
hasattr(obj, "__gt__")
# Python 3.X
def is_sortable(obj):
cls = obj.__class__
return cls.__lt__ != object.__lt__ or \
cls.__gt__ != object.__gt__
Python 2 和 3 需要不同的函数,因为 Python 3 中的未绑定方法、方法包装器和其他内部事物也发生了许多其他变化。
阅读此链接,您想更好地了解 Python 中的可排序对象:
http://python3porting.com/problems.html#unorderable-types-cmp-and-cmp
http://docs.python.org/2/howto/sorting.html#the-old-way-using-the-cmp-parameter
PS:这是对我的第一个答案的完整重新编辑,但是因为我更好地调查了这个问题并且对此有了更清晰的想法,所以需要它:)
遗憾的是,仅检查您的对象是否实现lt是不够的。numpy 使用 '<' 运算符返回一个布尔数组,它没有真值。SQL Alchemy 使用它返回一个查询过滤器,它又没有真值。普通集合使用它来检查子集关系,因此
set1 = {1,2}
set2 = {2,3}
set1 == set2
False
set1 < set2
False
set1 > set2
False
我能想到的最好的部分解决方案(从未知类型的单个对象开始)是这样的,但是通过丰富的比较,似乎正式不可能确定可订购性:
if hasattr(x, '__lt__'):
try:
isOrderable = ( ((x == x) is True) and ((x > x) is False)
and not isinstance(x, (set, frozenset)) )
except:
isOrderable = False
else:
isOrderable = False
已编辑
据我所知,所有列表都是可排序的,所以如果您想知道列表是否“可排序”,答案是肯定的,不知道它有什么元素。
class C:
def __init__(self):
self.a = 5
self.b = "asd"
c = C()
d = True
list1 = ["abc", "aad", c, 1, "b", 2, d]
list1.sort()
print list1
>>> [<__main__.C instance at 0x0000000002B7DF08>, 1, True, 2, 'aad', 'abc', 'b']
您可以确定您认为“可排序”的类型并实现一种方法来验证列表中的所有元素是否都是“可排序的”,如下所示:
def isSortable(list1):
types = [int, float, str]
res = True
for e in list1:
res = res and (type(e) in types)
return res
print isSortable([1,2,3.0, "asd", [1,2,3]])