python3 為什麼取消了sort方法中的cmp參數?
初學python。
今天在做Leetcode的題目Largest Number:Given a list of non negative integers, arrange them such that they form the largest number.
For example, given [3, 30, 34, 5, 9], the largest formed number is 9534330.
Note: The result may be very large, so you need to return a string instead of an integer.
寫了這樣一個sort方法:
nums.sort(cmp = lambda x,y: cmp(str(x) + str(y), str(y) + str(x)))
但是發現python3不支持cmp了。
在python官網文檔裡面看到需要用functools.cmp_to_key函數來轉換。看了下這個函數的代碼,是生成了一個中間的類:
def cmp_to_key(mycmp):
"""Convert a cmp= function into a key= function"""
class K(object):
__slots__ = ["obj"]
def __init__(self, obj):
self.obj = obj
def __lt__(self, other):
return mycmp(self.obj, other.obj) &< 0 def __gt__(self, other): return mycmp(self.obj, other.obj) &> 0
def __eq__(self, other):
return mycmp(self.obj, other.obj) == 0
def __le__(self, other):
return mycmp(self.obj, other.obj) &<= 0 def __ge__(self, other): return mycmp(self.obj, other.obj) &>= 0
def __ne__(self, other):
return mycmp(self.obj, other.obj) != 0
__hash__ = None
return K
對於這題,直接用sort的key參數應該怎麼寫呢(難道是自己手動去生成上面這個K類?
python3去掉cmp參數的好處在哪裡呢?
使用functools.cmp_to_key 即可。
附通過的代碼:class Solution:
# @param {integer[]} nums
# @return {string}
def largestNumber(self, nums):
from functools import cmp_to_key
key = cmp_to_key(lambda x,y: int(y+x)-int(x+y))
res = "".join(sorted(map(str, nums), key=key)).lstrip("0")
return res or "0"
第一次見這種方式,查看了一下文檔,感覺挺有意思的,特別是cmp_to_key的實現。
原來那種cmp函數的模式是每次直接給你兩個元素,你返回它們的大小關係。由於排序過程中同一個元素會被拿去跟別的不同元素cmp很多次,可能會有性能問題。
新的key函數這種模式並不直接比較任意兩個原始元素,而是通過key函數把那些元素轉換成一個個新的可比較對象,也就是元素的key,然後用元素的key代替元素去參與比較。如果元素key之間的比較操作比原始元素之間的比較操作效率高的話,那麼就能提高性能。
key函數的直接功能就是傳入一個元素,返回一個可比較對象。如果原始元素本來就是可比較對象,比如數字、字元串,那麼不考慮性能優化可以直接sort(key=lambda e: e)。Sorting HOW TO中還舉了另外幾個例子,可以看出在某些情況下這種基於key函數的設計還能夠簡化代碼。
不過這種基於key函數的設計傾向於每個元素的大小有個絕對標準,跟其它元素無關的情況(感覺這種應該有個更專業的說法?)。而在你的代碼場景里,單個元素並不沒有一個絕對的大小……所以有點不太適合key函數的這種方式,cmp_to_key可能是最好的一種方案了。
不知道你為什麼不想直接使用cmp_to_key?自己實現的話,只重載__lt__就行了。
假設求 key 的操作不是O(1) 的,或者說常數非常大,那麼用 key=lambda 的形式可以把 key 緩存下來,從而提速不過,感覺有的時候,還是cmp方便(尤其是習慣了C++的stl)
Python3 裡面sort是用 key = lambda ....來排序的吧以下搬運自 http://python3porting.com/preparing.htmlThis(key) is easier to use and faster to run. When using the cmp parameter, the sorting compares pairs of values, so the compare-function is called multiple times for every item. The larger the set of data, the more times the compare-function is called per item. With the key function the sorting instead keeps the key value for each item and compares those, so the key function is only called once for every item. This results in much faster sorts for large sets of data.
結合---知之 答案,找到這個,比python2慢不少
from functools import cmp_to_key
num = input()
l = input().split(" ")
l.sort(key=cmp_to_key(lambda a, b: (int(a + b) &> int(b + a)) - (int(a + b) &< int(b + a))), reverse=True)
print("".join(l))
偶然路過看到這個問題,用Python3試了一下,沒有cmp確實難寫很多
print("".join(map(str, sorted(a_list, key=lambda x: str(x).ljust(max(map(lambda i: len(str(i)),a_list)), str(x)[-1]), reverse=True))))
推薦閱讀:
※為什麼C++中會把文件操作抽象為fstream?
※為什麼 Python 3.0 設計成不與 Python 2.X 兼容?主要有哪些地方需要突破才導致這一決定?
※怎樣才叫 「精通」 C語言?
※有沒有合適的學習路線來學習封裝在IDE下的原理?
※如何開發中文演算法?