<lambda>()缺少2个必需的位置参数:“ y”和“ z”

时间:2018-11-24 04:46:50

标签: python

我已经看了好几次了,但仍然不明白这里有什么问题。这是下面写的余弦相似度函数,也是用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跟踪(最近一次通话)    在()中   ----> 1个cosine_sim(firstvector,secondvector)

     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”

1 个答案:

答案 0 :(得分:3)

您的reduce调用返回三个tuple,因此您要以lambda x, y, z作为三个x来调用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)

在可能的情况下为变量提供更好的名称,这是相当不错的代码(并且可能更快地启动)。