- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
Python 3.x 的 sorted()
不能依赖函数对异构序列进行排序,因为大多数不同类型对是不可排序的(数字类型,如 int
、float
、decimal.Decimal
等是一个异常(exception)):
Python 3.4.2 (default, Oct 8 2014, 08:07:42)
[GCC 4.8.2] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> sorted(["one", 2.3, "four", -5])
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: unorderable types: float() < str()
相比之下,没有自然顺序的对象之间的比较是任意的,但在 Python 2.x 中是一致的,因此 sorted()
有效:
Python 2.7.8 (default, Aug 8 2014, 14:55:30)
[GCC 4.8.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> sorted(["one", 2.3, "four", -5])
[-5, 2.3, 'four', 'one']
为了在 Python 3.x 中复制 Python 2.x 的行为,我编写了一个类用作 sorted()
的 key
参数,它依赖于sorted()
是 guaranteed 的事实仅使用小于比较:
class motley:
def __init__(self, value):
self.value = value
def __lt__(self, other):
try:
return self.value < other.value
except TypeError:
return repr(type(self.value)) < repr(type(other.value))
示例用法:
>>> sorted(["one", 2.3, "four", -5], key=motley)
[-5, 2.3, 'four', 'one']
到目前为止,还不错。
但是,当使用包含复数的特定序列调用sorted(s, key=motley)
时,我注意到一个令人惊讶的行为:
>>> sorted([0.0, 1, (1+0j), False, (2+3j)], key=motley)
[(1+0j), 0.0, False, (2+3j), 1]
我原以为 0.0
、False
和 1
属于一组(因为它们是可相互排序的),而 (1+0j)
和 (2+3j)
在另一个(因为它们是同一类型)。这个结果中的复数不仅彼此分离,而且其中一个复数位于一组可相互比较但不可与之比较的对象的中间,这一事实有些令人费解。
这是怎么回事?
最佳答案
您不知道比较的顺序是什么,甚至不知道比较了哪些项目,这意味着您无法真正知道您的 __lt__
会产生什么影响。会有。您定义的 __lt__
有时取决于实际值,有时取决于类型的字符串表示形式,但在排序过程中,这两种版本都可能用于同一对象。这意味着您的排序不仅仅由列表中的对象决定,还可能取决于它们的初始顺序。这反过来意味着仅仅因为对象可以相互比较并不意味着它们会被放在一起;他们之间可能被一个无与伦比的物体“挡住了”。
您可以通过放入一些调试打印来查看正在比较的内容,从而了解正在发生的事情:
class motley:
def __init__(self, value):
self.value = value
def __lt__(self, other):
fallback = False
try:
result = self.value < other.value
except TypeError:
fallback = True
result = repr(type(self.value)) < repr(type(other.value))
symbol = "<" if result else ">"
print(self.value, symbol, other.value, end="")
if fallback:
print(" -- because", repr(type(self.value)), symbol, repr(type(other.value)))
else:
print()
return result
然后:
>>> sorted([0.0, 1, (1+0j), False, (2+3j)], key=motley)
1 > 0.0
(1+0j) < 1 -- because <class 'complex'> < <class 'int'>
(1+0j) < 1 -- because <class 'complex'> < <class 'int'>
(1+0j) < 0.0 -- because <class 'complex'> < <class 'float'>
False > 0.0
False < 1
(2+3j) > False -- because <class 'complex'> > <class 'bool'>
(2+3j) < 1 -- because <class 'complex'> < <class 'int'>
[(1+0j), 0.0, False, (2+3j), 1]
例如,您可以看到基于类型的排序用于将复数与 1 进行比较,但不用于比较 1 和 0。同样 0.0 < False
出于“正常”原因,但是 2+3j > False
出于基于类型名称的原因。
结果是排序1+0j
到开头,然后离开2+3j
它高于 False 的地方。它甚至从不尝试将两个复数相互比较,并且将它们都比较的唯一项目是 1。
更一般地说,您的方法可以通过对所涉及类型的名称进行适当的选择来实现不及物排序。例如,如果您定义类 A、B 和 C,这样可以比较 A 和 C,但在与 B 比较时它们会引发异常,那么通过创建对象 a
, b
和 c
(来自各自的类(class))使得c < a
, 你可以创建一个循环 a < b < c < a
. a < b < c
将是真的,因为类将根据它们的名称进行比较,但是 c < a
因为可以直接比较这些类型。对于不及物排序,不可能有“正确”的排序顺序。
你甚至可以使用内置类型来做到这一点,尽管它需要一点创意来思考类型名称按正确字母顺序排列的对象:
>>> motley(1.0) < motley(lambda: 1) < motley(0) < motley(1.0)
True
(因为 'float' < 'function'
:-)
关于python - 为什么这个用于对异构序列进行排序的关键类表现得很奇怪?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26567667/
我正在用 C++ 开发一个程序,我必须实现一个 cron。由于不同的原因,这个 cron 应该每小时和每 24 小时执行一次。我的第一个想法是创建一个独立的 pthread 并在每次 1h 内休眠。这
我需要向同一场景几何添加多个体素(立方体等于),但每个体素具有不同的纹理。 我的体素超过 500 个,导致性能出现严重错误。 这是我的代码: texture = crearTextura(voxel.
对于 MySQL 数据库,我有 2 个场景,我不确定该选择哪一个,并且对于一些表我也遇到了同样的困境。 我正在制作一个仅供成员(member)访问的网络应用程序。每个成员都有自己的交易、费用和“列表”
我想知道一个简单的事情: 当设置一个被所有 child 继承的样式时,是否建议最具体? Structure: html > body > parent_content > wrapper > p 我想
很难说出这里要问什么。这个问题模棱两可、含糊不清、不完整、过于宽泛或夸夸其谈,无法以目前的形式得到合理的回答。如需帮助澄清此问题以便重新打开,visit the help center . 关闭 1
这些天我正在阅读有关 JPA 的内容。我了解到可以在 JPQL 中使用 explicit 或 implicit JOIN。 显式加入 em.createQuery(“SELECT b.title, p
我有一种情况需要连接几个字符串以形成一个类的 id。基本上,我只是在列表中循环以获取对象的 ToString 值,然后将它们连接起来。 foreach (MyObject o in myList)
我正在检查我的游戏在拖尾效果下的性能会降低多少。但我注意到每秒的操作次数更多了。这怎么可能? 这是怎么回事... context.fillRect(0, 0, 500, 500); // cl
如果我可以选择使用全局变量或传递变量,哪个选项在速度和内存使用方面更好? // global variable function func(){ global $var; echo $var;
我有一个类似这样的表“tbl”:ID bigint(20) - 主键,自增字段1字段2字段3 该表有 60 万多行。 查询:SELECT * from tbl ORDER by ID LIMIT 60
谁能告诉我,我如何比较 TSP 最优和启发式算法?我已经实现了 TSP,但不知道如何比较它们。事实上,我怎样才能找到 TSP 的最优成本?有什么方法或猜测吗? 谢谢 最佳答案 用众所周知的基准实例检查
我有一个 NSTextStorage里面有长文本(比如一本书有 500 页,当前字体在设备上超过 9000 页)。我以这种方式为 textcontainer 分发此文本: let textStorag
我有一个根据邮政编码搜索项目的应用程序。 在搜索邮政编码时,我返回了来自该城市/社区的所有产品(通过解析邮政编码完成)。 我现在需要根据与原始邮政编码的距离对这些产品进行分类。 我将纬度/经度存储在数
我有许多进程(大约100到1000个进程),每个进程都必须向其他进程(例如大约10个)发送一些数据。 (通常,但不一定总是这样,如果A发送给B,B也发送给A。)每个进程都知道必须从哪个进程接收多少数据
我知道无状态组件使用起来更舒服(在特定场景下),但是既然你不能使用shouldComponentUpdate,这是否意味着组件将在每次props更改时重新渲染?我的问题是,使用带有智能 shouldC
我正在研究 Google Pagespeed 的加速页面加载时间指南列表。其中之一是缩小 CSS 和 JS 文件。 由于这些文件经常更改,我正在考虑使用 PHP 脚本根据请求(来自浏览器)即时缩小此脚
我正在尝试从下表构建 SQL 查询(示例): Example of table with name "performances" 这是带有运动表现的表格。我想从这个表中选择每个学科和一组一个或多个类别
假设我们有一个字符串 var "sA",我想检查字符串 "123"是否在 sA 的末尾。 什么更好,为什么: if(sA.length() > 2) sA.substr(sA.length()-3)
关于受这篇文章启发的可参数化查询 LINQ group by property as a parameter我获得了一个很好的参数化查询,但在性能上有一个缺点。 public static void
| 和| 之间有什么主要区别吗?和 + 从长远来看会影响代码的性能吗?或者都是 O(1)?我正在使用的代码是这样的: uint64_t dostuff(uint64_t a,uint64_t b){
我是一名优秀的程序员,十分优秀!