__Python中类的键参数
我有一个向量数组,我想按长度对它们进行排序:__Python中类的键参数,python,sorting,key,Python,Sorting,Key,我有一个向量数组,我想按长度对它们进行排序: class Vector: def __init__(self, x, y): self.x, self.y = x, y def __add__(a, b): return Vector(a.x + b.x, a.y + b.y) def __str__(a): return str(a.x) + ' ' + str(a.y) + '\n' def __key
class Vector:
def __init__(self, x, y):
self.x, self.y = x, y
def __add__(a, b):
return Vector(a.x + b.x, a.y + b.y)
def __str__(a):
return str(a.x) + ' ' + str(a.y) + '\n'
def __key__(self):
return self.x * self.x + self.y * self.y
a = []
a.append(Vector(1,2))
a.append(Vector(1, 1))
a.sort()
print("".join(map(str,a)))
上面写着:“无序类型:Vector()lt
,gt
。。方法。但是我想在不使用cmp
的情况下进行排序。有可能吗?lt/le/gt/ge/eq/ne
[…]所谓的“丰富比较”方法,以及
优先于_cmp__()的比较运算符
如果您实现了一个方法,那么它应该用于比较/排序操作。我将实现
\uult\uuuuu
和\uuuuuu eq\uuu
,然后使用类装饰器来获取其余的比较方法
如果这样对向量进行排序没有意义,则始终可以使用键关键字排序(或排序):
这里有两种变体:在Vector
类中实现\uuuu cmp\uuuu
函数或以这种方式执行排序:
...
a.sort(key=Vector.__key__)
请注意,您可能不应该使用\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu
作为其中一个方法的名称。由下划线对括起来的方法名是为规范中的特殊方法保留的(这意味着Guido可以随时决定将\uuuuu key\uuuu
添加为python数据模型的一部分,并且您的方法可能会导致一些非常有趣的(不希望的)行为),您可能需要查看numpy
。它提供了“ndarray”,其行为与向量非常相似,支持一种非常有趣(且有用)的索引形式,并用C语言完成所有数学运算,这使它们比您自己实现的速度快了一点。@mgilson似乎OP希望\uuuuuuu key\uuuuu
已经被定义为Python数据模型的一部分,行为类似于键
关键字参数到列表。排序
。次要建议:\uuuu str\uuuuu
不应返回换行符\n
,让它由打印
,连接
等语句/函数处理,通常将第一个参数命名为方法self
,而不是a
(除非它是@staticmethod
或其他东西)。这不是必需的,但是当我阅读你的代码时,它迫使我做了一个双重的考虑,因为这个约定在我的脑海中根深蒂固。我建议将\uuuuuuu key\uuuuu
方法重命名为\uu len\uuuuu
,因为返回的值实际上是向量的长度。然后使用a.sort(key=len)
,这会更清楚地显示意图。@lazyr当然不会\uuuu len\uuuu
表示序列的长度;Python希望它返回一个整数。(另外,当前返回的值是长度的平方。)@lazyr-我同意\uuuuu key\uuuu
不是最好的名称的原则(即使它可能意味着将来某个特定的东西,它也不是很具体),但是\uu len\uuuuu
有点可疑,因为帮助(len)
说它是“序列或映射的项数”。我可能会将其定义为一个单独的函数(而不是方法),称为norm
。此外,值得指出的是\uu cmp\uu
在Python3.x中消失了(OP可能正在使用该函数)值得指出的是,Python3中不再使用\uu\cmp\uu
。x@mgilson事实上,考虑到print
的用法,OP可能已经在使用Py3.@Ivc——是的,类声明使用“旧式”语法(尽管这可能只是因为OP不知道总是从python 2.x中的对象继承)这很简洁,但语义上有点不确定:向量并不是完全按长度排序的,因为例如(0,1)和(1,0)是不同的,但比较起来是相等的。@Katrielex——这有点正确。例如,你可以自由地实现\uuuueq\uuuu
和\uuuult\uuuuuuu
,但你认为合适。你可以将\uuuuueq\uuuuu
定义为self.x==other.x和self.y==other.y
。在这种特殊情况下,我真的看不出一个向量是如何定义的。”小于“另一个,所以在本例中,我可能默认使用键
进行排序,但我认为我应该包括functools.total_ordering
,因为它更像OP试图做的事情。(无论如何,它也是一个有用的装饰器)。我认为这是一个很酷的想法,我认为它应该基于。问题是:total\u ordering
是否定义了\uu gt\uuu
,当x
和y
相等时返回False
,并且似乎是从源代码开始的。这种情况下的结果将不是total order,而是a;total h是什么这是真正的关系,而不是顺序。尽管回顾这一点,\uuu eq\uuu
对于两个不同的向量返回true的问题仍然存在。这可能并不理想……总体顺序有一些微妙的缺陷:
...
a.sort(key=Vector.__key__)