Python 一行:按多个相互依赖的键排序
Python One-Liner: Sorting by multiple, interdepending keys
免责声明:这个问题是关于我的,希望其他人能更好地理解 Python。我的问题不止一行就能轻松解决,我知道。
假设我有两个函数 f(x), g(x,y),这样我就可以将元组 ( f(x), g(x,f(x)) ) 计算为 x 的函数。
我想通过这两个键对列表 X 进行排序,但是计算 f(x) 很昂贵,所以我只想对每个 x 执行一次。我目前的解决方案是:
X_s = sorted( X , key = lambda x: (lambda y: ( y , g(x,y) ) )( f(x) ) )
我可以在不使用两个 lambda 函数的情况下实现同样的效果吗?
我喜欢拼图,所以我试了一下 :) 我设法在给定条件下解决了这个问题,但只是以一种非常丑陋的方式:
X_s = sorted(X, key=lambda x: [(f0, g(x, f0)) for f0 in [f(x)]][0])
因此,绝对可以用一个 lambda 函数在一行中完成此操作,但我必须用列表理解替换第二个 lambda。
这是我使用生成器的建议(有点冗长,但应该可以解决问题):
from operator import itemgetter
X_s = sorted(((f, g(x,f)) for x,f in ((x,f(x)) for x in X)), key=itemgetter(0,1))
顺便说一句,我知道那是 2 行,但第一行只是导入了一个标准模块以使对多个键的排序更具可读性(我更喜欢它而不是 lambda)。
编辑:
请注意,我的原始答案并没有完全给出您要求的输出。应该这样做(尽管更冗长):
X_s = [y[2] for y in sorted(((f,g(x,f),x) for x,f in ((x,f(x)) for x in X)), key=itemgetter(0,1))]
没有一个漂亮的单行。但是,使用更少的 lambda 进行混淆的单行代码有很多选择。
例如,可以像这样使用单个 lambda 表达式
X_s = [a, for (b, a) in sorted(zip(map(f, X), X), key=lambda y,x: (y, g(x,y)))]
或没有任何 lambdas
X_s = [x for (_, _, x) in sorted([(y, g(x,y), x) for (x,y) in zip(X, map(f, X))])]
但这些总是丑陋的。除了玩闹的情况,你应该用一个真正的循环来解决这个问题。
免责声明:这个问题是关于我的,希望其他人能更好地理解 Python。我的问题不止一行就能轻松解决,我知道。
假设我有两个函数 f(x), g(x,y),这样我就可以将元组 ( f(x), g(x,f(x)) ) 计算为 x 的函数。 我想通过这两个键对列表 X 进行排序,但是计算 f(x) 很昂贵,所以我只想对每个 x 执行一次。我目前的解决方案是:
X_s = sorted( X , key = lambda x: (lambda y: ( y , g(x,y) ) )( f(x) ) )
我可以在不使用两个 lambda 函数的情况下实现同样的效果吗?
我喜欢拼图,所以我试了一下 :) 我设法在给定条件下解决了这个问题,但只是以一种非常丑陋的方式:
X_s = sorted(X, key=lambda x: [(f0, g(x, f0)) for f0 in [f(x)]][0])
因此,绝对可以用一个 lambda 函数在一行中完成此操作,但我必须用列表理解替换第二个 lambda。
这是我使用生成器的建议(有点冗长,但应该可以解决问题):
from operator import itemgetter
X_s = sorted(((f, g(x,f)) for x,f in ((x,f(x)) for x in X)), key=itemgetter(0,1))
顺便说一句,我知道那是 2 行,但第一行只是导入了一个标准模块以使对多个键的排序更具可读性(我更喜欢它而不是 lambda)。
编辑:
请注意,我的原始答案并没有完全给出您要求的输出。应该这样做(尽管更冗长):
X_s = [y[2] for y in sorted(((f,g(x,f),x) for x,f in ((x,f(x)) for x in X)), key=itemgetter(0,1))]
没有一个漂亮的单行。但是,使用更少的 lambda 进行混淆的单行代码有很多选择。
例如,可以像这样使用单个 lambda 表达式
X_s = [a, for (b, a) in sorted(zip(map(f, X), X), key=lambda y,x: (y, g(x,y)))]
或没有任何 lambdas
X_s = [x for (_, _, x) in sorted([(y, g(x,y), x) for (x,y) in zip(X, map(f, X))])]
但这些总是丑陋的。除了玩闹的情况,你应该用一个真正的循环来解决这个问题。