在Python 2和3中运行函数而不指定参数

时间:2016-01-06 23:49:03

标签: python python-2.7 python-3.x

我有一些代码:

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'

2 个答案:

答案 0 :(得分:3)

Python 3仅处理key函数,而不处理cmp函数。在这种情况下(像许多情况一样),这使得它变得更加简单。您希望按长度排序,因此请直接使用key len进行排序(并且作为错误说明,必须通过关键字传递,而不是按位置传递):

z.sort(key=len)

这会对z中的所有长度进行一次性预先计算,只计算一次len(总计n len次调用);然后使用这些长度对z进行排序。对于cmplenlog2(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使用)