Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/310.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/sorting/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
__Python中类的键参数_Python_Sorting_Key - Fatal编程技术网

__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__)