我看了很多并且阅读了很多问题,但是我无法弄清楚如何给sort方法的关键字赋予两个参数,所以我可以进行更复杂的比较。
示例:
class FruitBox():
def __init__(self, weigth, fruit_val):
self.weigth = weigth
self.fruit_val = fruit_val
我想通过fruit_val比较FruitBox,但是!它们的箱子也比其他箱子大。
所以它会是:
f1 = FruitBox(2,5)
f2 = FruitBox(1,5)
f3 = FruitBox(2,4)
f4 = FruitBox(3,4)
boxes = [f1,f2,f3,f4]
boxes.sort(key = ???) # here is the question
预期结果:
=> [FruitBox(2,4),FruitBox(3,4),FruitBox(1,5),FruitBox(2,5)]
当我这样做时,有没有办法发送一个带有2个参数的函数
def sorted_by(a,b):
#logic here, I don't know what will be yet
我做了
boxes.sort(key=sorted_by)
它抛出:
Traceback (most recent call last):
File "python", line 15, in <module>
TypeError: sort_by_b() missing 1 required positional argument: 'b'
如何将两个参数赋予排序键?
答案 0 :(得分:7)
这个答案专门回答:
如何将两个参数赋予排序键?
旧方式比较排序方法已经在Python 3中消失了,就像你在Python 2中那样:
def sorted_by(a,b):
# logic here
pass
boxes.sort(cmp=sorted_by)
但如果你必须使用Python 3,它仍然存在,但在模块functool
中,它的目的是将cmp
转换为key
:
import functools
cmp = functools.cmp_to_key(sorted_by)
boxes.sort(key=cmp)
排序的首选方法是创建一个键函数,该函数返回基于排序的权重。请参阅Francisco’s回答。
答案 1 :(得分:3)
Odd and Ends上的文档部分说:
排序例程保证在两个对象之间进行比较时使用
__lt__()
。因此,通过定义__lt__()
方法,可以轻松地向类中添加标准排序顺序。
在您的示例中,转换为将__lt__()
添加到FruitBox
类:
class FruitBox():
def __init__(self, weigth, fruit_val):
self.weigth = weigth
self.fruit_val = fruit_val
def __lt__(self, other):
# your arbitrarily complex comparison here:
if self.fruit_val == other.fruit_val:
return self.weight < other.weight
else:
return self.fruit_val < other.fruit_val
# or, as simple as:
return (self.fruit_val, self.weight) < (other.fruit_val, other.weight)
然后像这样使用它:
sorted(fruitbox_objects)
答案 2 :(得分:2)
如果你想使用两个键进行排序,你可以这样做(我想你想先按fruit_val
然后按weight
排序:
boxes.sort(key=lambda x: (x.fruit_val, x.weigth))
答案 3 :(得分:0)
您可以使用key
成员变量fruit_val
参数进行排序:
boxes = [f1,f2,f3,f4]
boxes.sort(key=lambda x:x.fruit_val)
print([i.__dict__ for i in boxes])
输出:
[{'fruit_val': 4, 'weigth': 2}, {'fruit_val': 4, 'weigth': 3}, {'fruit_val': 5, 'weigth': 2}, {'fruit_val': 5, 'weigth': 1}]