我有一些代码:
def __petric(terms):
while len(terms) > 1:
z = []
for i in terms[0]:
for j in terms[1]:
z.append(list(set(i+j)))
del terms[0]
del terms[0]
z.sort(__sortByLen)
__simplify(z)
terms.insert(0, z)
return terms
z.sort
行调用的函数有2个参数。
在Python 2中,它会运行并提供预期的结果。
但在Python 3中,这会产生错误:
'TypeError: must use keyword argument for key function'
我的__sortByLen函数
def __sortByLen(x,y):
if len(x) > len(y):
return 1
elif len(x) < len(y):
return -1
else:
return 0
和不同的功能,相同的概念
def __sortByCost(x,y):
cx=__getCost(x) #cost of the first
cy=__getCost(y) #cost of the second
if cx > cy:
return 1
elif cx < cy:
return -1
else:
return 0
当我将其更改为z.sort(key=__sortByLen)
时,我收到了另一个错误
TypeError: __sortByLen() missing 1 required positional argument: 'y'
答案 0 :(得分:3)
Python 3仅处理key
函数,而不处理cmp
函数。在这种情况下(像许多情况一样),这使得它变得更加简单。您希望按长度排序,因此请直接使用key
len
进行排序(并且作为错误说明,必须通过关键字传递,而不是按位置传递):
z.sort(key=len)
这会对z
中的所有长度进行一次性预先计算,只计算一次len
(总计n
len
次调用);然后使用这些长度对z
进行排序。对于cmp
次len
次log2(n)
次呼叫,旧的n * log2(n)
方法计算每次 len
大约len
次{实际上,向上两倍,因为您没有在cmp
函数中保存key
。
因此,对于1024个元素,基于len
的方法只需要调用cmp
1024次,不多也不少;您尝试的基于len
的方法最终可能会对key
执行多达20倍的呼叫(实际上,稍微低一点,大约8000-18,000次呼叫,如果数据是绝对最少2046次已经按TimSort galloping mode排序了,但仍然是cmp
个数字的两倍,因为您需要1023 len
次来电,每次调用都会计算两个key
。
如果key
函数的结果是内置的Python(您的int
函数返回key
,那么这就是这种情况)并且您正在使用Python参考翻译,然后节省更多;当排序过程中不需要执行Python字节代码时,排序运行得更快。当使用返回内置函数的key
时,在预先排序cmp
计算之后,在实际排序期间不执行任何字节代码,因此所有工作都在C层完成,甚至运行比严格的算法分析表明要快。对于cmp
,自定义@echo off
set plvl=1
set pexp=0
set pexpend=100
set aiexp=10
set pexplvl2=3.1
if "%plvl%"=="1" set /a pexp=%pexp% + %pexpend% / %aiexp% * %pexplvl2%
函数几乎总是用Python编写,因此每次比较都需要回调字节码解释器,从而减慢速度。
答案 1 :(得分:0)
将z.sort(__sortByLen)
更改为z.sort(key=__sortByLen)
虽然您还应确保__sortByLen
具有关键功能的正确行为,而不是cmp函数(由python2使用)