Python中两个列表的点积

9
我需要编写一个函数dot(L, K),用于输出列表L和K的点积。如果这两个输入列表的长度不相等,dot函数应输出0。如果这两个列表都为空,dot也应该输出0。您应该假设输入列表只包含数字值。
目前我有以下代码:
def dot( L, K ):
    if len[L]!=len[K]:
        return 0
    elif L == '' or L == []:
        return 0
    else:
        return sum(L[0]*K[0], L[1]*K[1], ect.)

有人能帮我吗?因为最后一行我想不出该怎么做!


(注意:保留HTML标记)

尝试在最后一行使用for循环。我假设这是一个作业,否则你可以使用numpy.dot - Akavall
1
这似乎是一道作业题。看一下 zip 函数。 - Azsgy
一个更符合 Python 风格的函数会在长度不匹配时返回 None,但是嘿,我猜你得写老师想要的东西。 :) - PM 2Ring
你被告知应该假设输入列表仅包含数字值。那么你在哪里将L与空字符串进行比较? - David Hammen
5个回答

24

您可以使用列表推导式完成此操作:

def dot(K, L):
   if len(K) != len(L):
      return 0

   return sum(i[0] * i[1] for i in zip(K, L))

如果两个列表中任意一个为空,zip(K, L)将返回[]。然后,根据定义,sum([])将会返回0。


1
@BenjaminBrooks:FWIW,VHarisop的代码可以压缩为return sum(i*j for i,j in zip(K, L)) if len(K) == len(L) else 0,但这可能对你的老师来说有点太花哨了。 :) - PM 2Ring
5
@PM2Ring,我在想老师会对return len(K) == len(L) and sum(starmap(mul, zip(K, L))) or 0有何看法。 - Padraic Cunningham
1
@PadraicCunningham:好主意。我想知道老师是否知道itertools的存在... :) - PM 2Ring
想要补充一点:如果长度不相等,你可能希望“引发”一个错误,因为两个不同维度的向量的点积是没有定义的。 - shayaan

11

使用列表推导式,假设V1和V2是两个向量(列表):

 sum([x*y for x,y in zip(V1,V2)])

1
for循环返回一个数组,该数组的每个K*L元素都被乘以。然后sum函数添加每个元素并返回点积。
def dot(K,L):
    if len(K)==len(L) and len(K)!=0:
        return sum([K[n]*L[n] for n in range(len(K))])
    else:
        return 0

请解释一下为什么这样做可以解决问题。如果你只是贴出答案而没有任何解释,那对帮助并不会有很大的帮助。 - Serguei Fedorov
最后一行应该是return 0。对于那些太新而无法识别“zip”的人来说,这并不是非常有价值的答案,除了更清楚地阐明算法。 - Tom Zych

1

这是适用于任意大小向量的一行代码(您可能希望将其定义为更规范和易读的函数或更改代码以使用 sum 而不是最左侧的 reduce )。 它不会为非相等长度定义乘法,因为它不是标准点积定义的一部分--它只会在非相等长度上报告错误:

dotprod =lambda K, L:reduce(lambda z1, z2: z1+z2, map(lambda x: reduce(lambda x1, x2: x1*x2, x), zip(K, L)))

快速测试:
dotprod([1, 2, 3, 4], [5, 6, 7, 8])
Out[39]: 70
5+12+21+32
Out[40]: 70

如果您仍然希望包含长度检查和非相等乘法的定义:
dotprod =lambda K, L: reduce(lambda z1, z2: z1+z2, map(lambda x: reduce(lambda x1, x2: x1*x2, x), zip(K, L))) if len(K)==len(L) else 0

dotprod([1, 2, 3, 4], [5, 6, 7, 8])
Out[43]: 70
dotprod([1, 2, 3, 4], [5, 6, 7])
Out[44]: 0

0
    vector_a = [1., 2., 3.]
    vector_b = [2., 2., 2.]
    z=list(zip(vector_a,vector_b))
    a=sum([x*y for x,y in zip(vector_a,vector_b)])
      for m,n in z:
        print(str(m)+"*",str(n))
    print(a)

    #hope you got it `

使用Zip函数可以提供更少的复杂度,使其在点积或任何多个列表操作的情况下更有效。


3
没有任何解释的代码转储很少有帮助。Stack Overflow的目的是学习,而不是提供盲目复制粘贴的代码片段。请编辑您的问题,并解释它如何比原始帖子提供的更好。 - Chris

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接