Here is a pretty general method: It works with nested lists, lists of lists of arrays - regardless of whether the shapes of these arrays are different or equal. It also works when the data come clumped together in one single array, which is in fact the trickiest case. (Other methods posted so far will not work in this case.)
Let's start with the difficult case, one big array:
# create example
# pick outer shape and inner shape
>>> osh, ish = (2, 3), (2, 5)
# total shape
>>> tsh = (*osh, *ish)
# make data
>>> data = np.arange(np.prod(tsh)).reshape(tsh)
>>>
# recalculate inner shape to cater for different inner shapes
# this will return the consensus bit of all inner shapes
>>> ish = np.shape(data)[len(osh):]
>>>
# block them
>>> data_blocked = np.frompyfunc(np.reshape(data, (-1, *ish)).__getitem__, 1, 1)(range(np.prod(osh))).reshape(osh)
>>>
# admire
>>> data_blocked
array([[array([[0, 1, 2, 3, 4],
[5, 6, 7, 8, 9]]),
array([[10, 11, 12, 13, 14],
[15, 16, 17, 18, 19]]),
array([[20, 21, 22, 23, 24],
[25, 26, 27, 28, 29]])],
[array([[30, 31, 32, 33, 34],
[35, 36, 37, 38, 39]]),
array([[40, 41, 42, 43, 44],
[45, 46, 47, 48, 49]]),
array([[50, 51, 52, 53, 54],
[55, 56, 57, 58, 59]])]], dtype=object)
Using OP's example which is a list of lists of arrays:
>>> x = np.array([[1, 2, 3], [4, 5, 6]])
>>> y = np.array([[7, 8, 9], [0, 1, 2]])
>>> u = np.array([[3, 4, 5], [6, 7, 8]])
>>> v = np.array([[9, 0, 1], [2, 3, 4]])
>>> data = [[x, y], [u, v]]
>>>
>>> osh = (2,2)
>>> ish = np.shape(data)[len(osh):]
>>>
>>> data_blocked = np.frompyfunc(np.reshape(data, (-1, *ish)).__getitem__, 1, 1)(range(np.prod(osh))).reshape(osh)
>>> data_blocked
array([[array([[1, 2, 3],
[4, 5, 6]]),
array([[7, 8, 9],
[0, 1, 2]])],
[array([[3, 4, 5],
[6, 7, 8]]),
array([[9, 0, 1],
[2, 3, 4]])]], dtype=object)
And an example with different shape subarrays (note the v.T
):
>>> data = [[x, y], [u, v.T]]
>>>
>>> osh = (2,2)
>>> ish = np.shape(data)[len(osh):]
>>> data_blocked = np.frompyfunc(np.reshape(data, (-1, *ish)).__getitem__, 1, 1)(range(np.prod(osh))).reshape(osh)>>> data_blocked
array([[array([[1, 2, 3],
[4, 5, 6]]),
array([[7, 8, 9],
[0, 1, 2]])],
[array([[3, 4, 5],
[6, 7, 8]]),
array([[9, 2],
[0, 3],
[1, 4]])]], dtype=object)