You can do the trick building a special matrix by stacking the identity matrix multiplied by the values you want to use.
I will use a 3x3 matrix as an example, but the idea is the same for an arbitrary matrix:
Imagine we want to multiply the matrix:
A = np.array([
[1,0,1],
[0,1,0],
[0,0,1]
])
By [2, 3, and 5]. Without loops.
We can build a special matrix contatenating the identity to do this:
[ 2 * np.eye(3), 3 * np.eye(3), 5 * np.eye(3)]
[ 0 0 2 ] [ 0 0 3] [ 0 0 5 ]
[ 0 2 0 ] [ 0 3 0] [ 0 5 0 ]
[ 2 0 0 ] [ 3 0 0] [ 5 0 0 ]
We can do this with a list comprehension:
multiply_values = [2,3,5]
special_matrix = np.concatenate( [ x * eye(3) for x in multiply_values ], axis=1)
# special_matrix is:
# array([[2., 0., 0., 3., 0., 0., 5., 0., 0.],
# [0., 2., 0., 0., 3., 0., 0., 5., 0.],
# [0., 0., 2., 0., 0., 3., 0., 0., 5.]])
Now we can multiply the matrix in one step:
result = np.dot( , special_matrix)
# result is
array([[2., 0., 0., 3., 0., 0., 5., 0., 0.],
[0., 2., 0., 0., 3., 0., 0., 5., 0.],
[0., 0., 2., 0., 0., 3., 0., 0., 5.]])
Probably this large wide matrix is not what we need.
We can get the partial results slicing the resulting product:
result[:,0:3]
# array([[2., 0., 2.],
# [0., 2., 0.],
# [0., 0., 2.]])
We can process the slices with another comprehension:
[ special_matrix[:,x:x+3] for x in [0,3,6] ]
# or in a more general way
[ special_matrix[:,x:x+A.shape[0]] for x in list(range(0,A.shape[0]**2,A.shape[0] ]