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.

欢迎加入QQ群-->: 979659372 Python中文网_新手群

推荐PyPI第三方库


热门话题
java如何从sql查询中跳过元组结果中的索引   java无法在Hypersql上使用时间戳恢复时间   java如何使用JSQLParser获取Select子句的主体   mysql可以通过Java批处理调用SQL存储过程吗?   多参数迭代数组的java方法   安卓将数据从Firebase检索到ViewPager JAVA   java组织。阿帕奇。节俭。TBase vs org。阿帕奇。节约诱导前   java Firebase数据库和Android如何在注销时销毁“会话”?   在Java中使用toString修改字符串时StringBuilder的效率   java如何在安卓中根据整数大小对arrayList排序?   java先前工作的日期格式化代码在Micromax A111上不返回任何内容   java在servlet之间传输值   java Hibernate:为什么createQuery()会将包名附加到实体名?   java我可以右对齐图标以获得首选项吗?   java JavaFX 11部署失败:未能创建任务或类型JavaFX:com。太阳javafx。工具。ant:文件集   OSX约塞米蒂终端不会运行java MyClass。类,错误:无法找到或加载主类MyClass。班   什么是java。lang.Class<?>[]   反射为什么在更改字段的修饰符之前不能使用方法get(java.lang.reflect.Field#get)   java未能在java9下运行jmh测试