【问题标题】:<lambda>() missing 2 required positional arguments: 'y' and 'z'<lambda>() 缺少 2 个必需的位置参数:'y' 和 'z'
【发布时间】:2019-04-26 13:39:54
【问题描述】:

我已经看了好几遍,但仍然无法理解这里似乎有什么问题。这是下面写的余弦相似度函数,也是用 2 个向量调用的地方。

def cosine_sim(v1, v2):
     return (lambda x,y,z: x / sqrt(y * z))(reduce(lambda x,y: (x[0] + y[0] * y[1], x[1] + y[0]**2, x[2] + y[1]**2), izip(v1,v2),(0,0,0)))

cosine_sim(first_vector,second_vector)

错误:


TypeError Traceback(最近一次调用最后一次) 在 () ----> 1 cosine_sim(firstvector,secondvector)

in cosine_sim(v1, v2) 1 def cosine_sim(v1, v2): ----> 2 return (lambda x,y,z: x / sqrt(y * z))(reduce(lambda x,y: (x[0] + y[0] * y[1], x[ 1] + y[0]**2, x[2] + y[1]**2), izip(v1,v2),(0,0,0)))

TypeError: () 缺少 2 个必需的位置参数:'y' 和 'z'

【问题讨论】:

  • 您在单个元组 (reduce(lambda x,y: (x[0] + y[0] * y[1], x[1] + y[0]**2, x[2] + y[1]**2), izip(v1,v2),(0,0,0)) 上调用第一个 lambda 函数 lambda x,y,z: x / sqrt(y * z),因此 x 是一个 3 元素元组,y 和 z 未定义。而且,为什么这需要是一个具有多个匿名函数的单行代码??

标签: python


【解决方案1】:

您的reduce 调用返回三个-tuple,因此您将lambda x, y, zx 称为三个-tuple,并且没有yz 的参数。

最简单的解决方法是使用the splat operator, *,将reduce 的返回解包,因此三个-tuple 被转换为三个连续的位置参数:

def cosine_sim(v1, v2):
    return (lambda x,y,z: x / sqrt(y * z))(*reduce(lambda x,y: (x[0] + y[0] * y[1], x[1] + y[0]**2, x[2] + y[1]**2), izip(v1,v2),(0,0,0)))
    #                       change is here ^

请注意,单衬这非常丑陋,您最好将其(至少)制作成双衬,以降低复杂性。即使保留reduce,您也可以稍微简化一下:

def cosine_sim(v1, v2):
    x, y, z = reduce(lambda x,y: (x[0] + y[0] * y[1], x[1] + y[0]**2, x[2] + y[1]**2), izip(v1,v2),(0,0,0))
    return x / sqrt(y * z)

这基本上是您的 lambda 所尝试的,但开销较低(无需无缘无故调用更多函数)。

完全删除reduce 会使其稍长一些,但同样更易于解释:

def cosine_sim(v1, v2):
    x = y = z = 0
    for a, b in izip(v1, v2):
        x += a * b
        y += a ** 2
        z += b ** 2
    return x / sqrt(y * z)

如果可能的话,给变量取更好的名字,这是相当不错的代码(而且可能会更快启动)。

【讨论】:

    猜你喜欢
    • 2018-05-09
    • 2013-09-27
    • 2020-11-15
    • 2017-05-28
    • 2020-01-06
    • 1970-01-01
    • 2019-02-08
    • 2021-07-22
    • 1970-01-01
    相关资源
    最近更新 更多