Для достаточно больших массивов, самый быстрый метод здесь является einsum
A = numpy.array(A)
B = numpy.array(B)
out = numpy.einsum('ij, ij->i', A, B)
out = numpy.multiply(A, B).sum(1)
out = [sum(ai * bi for ai, bi in zip(a, b)) for a, b in zip(A, B)]
Он превосходит версию с множественным добавлением в 2 раза; версия для ознакомления в списке - несколько сотен раз медленнее.
На рисунке был создан с
import numpy
import perfplot
perfplot.show(
setup=lambda n: (numpy.random.rand(n, 3), numpy.random.rand(n, 3)),
kernels=[
lambda data: numpy.einsum('ij, ij->i', data[0], data[1]),
lambda data: numpy.multiply(data[0], data[1]).sum(1),
lambda data: [sum(ai * bi for ai, bi in zip(a, b)) for a, b in
zip(data[0], data[1])],
],
labels=['einsum', 'multiply+sum', 'sum+zip'],
n_range=[2**k for k in range(18)],
xlabel='len(a)',
logx=True,
logy=True,
)
numpy.dot не обрабатывает строчном скалярных произведений. –