我有一个要按多个key
排序的列表,例如:
L = [ ... ]
L.sort(key = lambda x: ( f(x), g(x) ))
这个很好用。但是,这会导致对g
的不必要调用,我希望避免这种调用(因为它可能很慢)。换句话说,我想部分地、懒惰地评估密钥。在
例如,如果f
对L
(即len(L) == len(set(map(f,L)))
)是唯一的,则不应调用g
。在
什么是最优雅/最具Python风格的方式?
我能想到的一种方法是定义一个自定义的cmp
函数(L.sort(cmp=partial_cmp)
),但在我看来,这比使用key
参数要简单得多。在
另一种方法是定义一个键包装类,该类接受生成器表达式来生成键的不同部分,并重写比较运算符以逐个进行比较。但是,我觉得一定有一个更简单的方法。。。在
编辑:我对通过多个函数进行排序的一般问题的解决方案感兴趣,而不仅仅是上面例子中的两个函数。在
您可以使用一个键对象来延迟求值并缓存
g(x)
:下面是一个使用示例:
^{pr2}$给定一个函数,可以创建如下LazyComparer类:
要从多个函数中生成一个lazy key函数,可以创建一个实用函数:
^{pr2}$它们一起使用可以这样:
它产生了
上面的@countcalls修饰符用于确认当
f1
返回很多 对于ties,调用g
来断开连接,但是当f2
返回不同的值时,g
未被调用。在NPE的解决方案在
Key
类中添加了记忆。有了上面的解决方案, 您可以在LazyComparer
类之外(独立于)添加备忘录:从而减少了对
g
的调用:您可以尝试使用^{} :
另一种可能性,甚至不那么优雅,但在适当的地方:
^{pr2}$第一版通用于任意数量的函数:
第二个版本一般化为任意数量的函数(但是还没有完全到位):
相关问题 更多 >
编程相关推荐