Here's an approach upon computing those linear indices in a broadcasted manner and then assigning into an zeros-initialized array -
def block_mat(list_, n = 2):
input_arr = np.array(list_).reshape(-1,4)
N = 2*n + 2
M = 2*N + 2
p,q = input_arr.shape
I,J,K = np.ix_(M*np.arange(n), N*np.arange(p), np.arange(q))
idx = I + J + K + N
out = np.zeros((N,N),dtype=input_arr.dtype)
out.flat[idx] = input_arr
out.flat[[0,-1]] = 1
return out
Sample runs -
1) Input elements :
In [497]: a,b,c,d,e,f,g,h = range(3,11)
In [498]: a,b,c,d,e,f,g,h
Out[498]: (3, 4, 5, 6, 7, 8, 9, 10)
2) Various n cases :
In [499]: block_mat([a,b,c,d,e,f,g,h], n = 2)
Out[499]:
array([[ 1, 0, 0, 0, 0, 0],
[ 3, 4, 5, 6, 0, 0],
[ 7, 8, 9, 10, 0, 0],
[ 0, 0, 3, 4, 5, 6],
[ 0, 0, 7, 8, 9, 10],
[ 0, 0, 0, 0, 0, 1]])
In [500]: block_mat([a,b,c,d,e,f,g,h], n = 3)
Out[500]:
array([[ 1, 0, 0, 0, 0, 0, 0, 0],
[ 3, 4, 5, 6, 0, 0, 0, 0],
[ 7, 8, 9, 10, 0, 0, 0, 0],
[ 0, 0, 3, 4, 5, 6, 0, 0],
[ 0, 0, 7, 8, 9, 10, 0, 0],
[ 0, 0, 0, 0, 3, 4, 5, 6],
[ 0, 0, 0, 0, 7, 8, 9, 10],
[ 0, 0, 0, 0, 0, 0, 0, 1]])
In [501]: block_mat([a,b,c,d,e,f,g,h], n = 4)
Out[501]:
array([[ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0],
[ 3, 4, 5, 6, 0, 0, 0, 0, 0, 0],
[ 7, 8, 9, 10, 0, 0, 0, 0, 0, 0],
[ 0, 0, 3, 4, 5, 6, 0, 0, 0, 0],
[ 0, 0, 7, 8, 9, 10, 0, 0, 0, 0],
[ 0, 0, 0, 0, 3, 4, 5, 6, 0, 0],
[ 0, 0, 0, 0, 7, 8, 9, 10, 0, 0],
[ 0, 0, 0, 0, 0, 0, 3, 4, 5, 6],
[ 0, 0, 0, 0, 0, 0, 7, 8, 9, 10],
[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 1]])