Python3中任何对象的安全比较(总排序)
safe-cmp的Python项目详细描述
在Python 2中,可以比较任何对象:
>>> None > 2 False >>> [] < object() True
但在Python 3中不再是这样了:
^{pr2}$但在许多情况下,它是有用的,例如:
- 排序异类列表(即包含多种类型对象的列表)
- 将对象与None进行比较(例如,查找列表的max(...)) 其中某些项可能是None)
- 编写泛型函数,该函数在 任意输入
safe_cmp提供安全排序和排序中的任何值的函数 Python 3。用奇特的数学术语,safe_cmp实现了所有 python3[1]中的值。在
safe_cmp实现了与python2兼容的安全排序版本 功能:
- safe_cmp:python3的cmp的python2兼容实现
- safe_sorted:安全版本的sorted(...)
- safe_min:安全版本的min(...)
- safe_max:安全版本的max(...)
并提供一个包装器-safe_order,它定义了 任何对象(例如,heterogeneous_list.sort(key=safe_order))。在
示例
对异类列表排序:
>>>fromsafe_cmpimportsafe_sorted,safe_order>>>items=[1,None,"foo",{},object]>>>list(safe_sorted(items))# Using "safe_sorted"[None,{},1,'foo',object]>>>items.sort(key=safe_order)# Using "safe_order" with key=>>>items[None,{},1,'foo',object]
查找包含空值的列表的最大值:
>>>fromsafe_cmpimportsafe_max>>>safe_max([1,None,3,None,4])4
Python 2 stylecmp非常有用:
>>>fromsafe_cmpimportsafe_cmp>>>safe_cmp(None,1)-1>>>safe_cmp(None,None)0>>>safe_cmp(1,None)1
注意:safe_cmp调用时将生成与python2兼容的结果 nan:
>>>fromsafe_cmpimportsafe_cmp>>>nan=float("NaN")>>>safe_cmp(nan,1)-1>>>safe_cmp(1,nan)1>>>safe_cmp(nan,nan)0
safe_sorted:
>>>fromsafe_cmpimportsafe_sorted>>>list(safe_sorted([nan,2,nan,1]))[nan,2,nan,1]
性能
目前,safe_cmp方法目前是在Python中实现的(相比之下 它们的不安全的内置对应项(在C中实现),所以 如果进行大型比较,性能将显著下降:
In [1]: %timeit safe_max(range(10000000)) 2.8 s ± 42 ms per loop (mean ± std. dev. of 7 runs, 1 loop each) In [2]: %timeit max(range(10000000)) 345 ms ± 6.23 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
不过,对于较小的比较而言,差异可以忽略不计:
In [1]: %timeit safe_max(1, 2) 682 ns ± 7.12 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each) In [2]: %timeit max(1, 2) 218 ns ± 6.87 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)
但是,如果有人对性能实现感兴趣,他们会感兴趣的 直接提供。在
此外,在明显的地方,已经实现了性能优化 (例如,缓存key=函数的结果)。在
[1] | More precisely, a total ordering of all values which can be ordered. This excludes ^{tt23}$, and any other values which are defined as having an undefined ordering. |
- 项目
标签: