Recursive function checking that the depths of nested lists in `arrays` all match. Mismatch raises a ValueError as described in the block docstring below. The entire index (rather than just the depth) needs to be calculated for each innermost list, in case an error needs to be
(arrays, parent_index=[])
| 475 | |
| 476 | |
| 477 | def _block_check_depths_match(arrays, parent_index=[]): |
| 478 | """ |
| 479 | Recursive function checking that the depths of nested lists in `arrays` |
| 480 | all match. Mismatch raises a ValueError as described in the block |
| 481 | docstring below. |
| 482 | |
| 483 | The entire index (rather than just the depth) needs to be calculated |
| 484 | for each innermost list, in case an error needs to be raised, so that |
| 485 | the index of the offending list can be printed as part of the error. |
| 486 | |
| 487 | Parameters |
| 488 | ---------- |
| 489 | arrays : nested list of arrays |
| 490 | The arrays to check |
| 491 | parent_index : list of int |
| 492 | The full index of `arrays` within the nested lists passed to |
| 493 | `_block_check_depths_match` at the top of the recursion. |
| 494 | |
| 495 | Returns |
| 496 | ------- |
| 497 | first_index : list of int |
| 498 | The full index of an element from the bottom of the nesting in |
| 499 | `arrays`. If any element at the bottom is an empty list, this will |
| 500 | refer to it, and the last index along the empty axis will be None. |
| 501 | max_arr_ndim : int |
| 502 | The maximum of the ndims of the arrays nested in `arrays`. |
| 503 | final_size: int |
| 504 | The number of elements in the final array. This is used the motivate |
| 505 | the choice of algorithm used using benchmarking wisdom. |
| 506 | |
| 507 | """ |
| 508 | if type(arrays) is tuple: |
| 509 | # not strictly necessary, but saves us from: |
| 510 | # - more than one way to do things - no point treating tuples like |
| 511 | # lists |
| 512 | # - horribly confusing behaviour that results when tuples are |
| 513 | # treated like ndarray |
| 514 | raise TypeError( |
| 515 | '{} is a tuple. ' |
| 516 | 'Only lists can be used to arrange blocks, and np.block does ' |
| 517 | 'not allow implicit conversion from tuple to ndarray.'.format( |
| 518 | _block_format_index(parent_index) |
| 519 | ) |
| 520 | ) |
| 521 | elif type(arrays) is list and len(arrays) > 0: |
| 522 | idxs_ndims = (_block_check_depths_match(arr, parent_index + [i]) |
| 523 | for i, arr in enumerate(arrays)) |
| 524 | |
| 525 | first_index, max_arr_ndim, final_size = next(idxs_ndims) |
| 526 | for index, ndim, size in idxs_ndims: |
| 527 | final_size += size |
| 528 | if ndim > max_arr_ndim: |
| 529 | max_arr_ndim = ndim |
| 530 | if len(index) != len(first_index): |
| 531 | raise ValueError( |
| 532 | "List depths are mismatched. First element was at depth " |
| 533 | "{}, but there is an element at depth {} ({})".format( |
| 534 | len(first_index), |
no test coverage detected