[英]python, sort list with two arguments in compare function
我看了很多並且閱讀了很多問題,但是我無法弄清楚如何給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'
如何給出排序鍵的兩個參數?
這個答案致力於回答:
如何給出排序鍵的兩個參數?
在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)
排序的首選方法是創建一個鍵函數,該函數返回基於排序的權重。 見弗朗西斯科的回答。
如果你想使用兩個鍵進行排序,你可以這樣做(我想你首先要通過fruit_val
然后按weight
排序:
boxes.sort(key=lambda x: (x.fruit_val, x.weigth))
關於Odd和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)
您可以使用帶有fruit_val
成員變量的key
參數進行排序:
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}]
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.