diff options
author | Charles Harris <charlesr.harris@gmail.com> | 2018-09-18 12:58:43 -0500 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-09-18 12:58:43 -0500 |
commit | d126ff7a8769fc918cf4e4ed92c7d8bbc7eef094 (patch) | |
tree | 0857edd7cefb64e54a765e0f68aded5e864b8945 | |
parent | c95c479c9aea704bf3f67bb9b0eb2a158673fb7b (diff) | |
parent | 6a3a236ca847785657b264576f9b34a20a24e957 (diff) | |
download | numpy-d126ff7a8769fc918cf4e4ed92c7d8bbc7eef094.tar.gz |
Merge pull request #11976 from eric-wieser/tweak-block-error-checks
MAINT/DOC: Show the location of an empty list in np.block
-rw-r--r-- | numpy/core/shape_base.py | 51 |
1 files changed, 35 insertions, 16 deletions
diff --git a/numpy/core/shape_base.py b/numpy/core/shape_base.py index 3e023c87b..30919ed7e 100644 --- a/numpy/core/shape_base.py +++ b/numpy/core/shape_base.py @@ -361,6 +361,14 @@ def stack(arrays, axis=0, out=None): return _nx.concatenate(expanded_arrays, axis=axis, out=out) +def _block_format_index(index): + """ + Convert a list of indices ``[0, 1, 2]`` into ``"arrays[0][1][2]"``. + """ + idx_str = ''.join('[{}]'.format(i) for i in index if i is not None) + return 'arrays' + idx_str + + def _block_check_depths_match(arrays, parent_index=[]): """ Recursive function checking that the depths of nested lists in `arrays` @@ -371,19 +379,23 @@ def _block_check_depths_match(arrays, parent_index=[]): for each innermost list, in case an error needs to be raised, so that the index of the offending list can be printed as part of the error. - The parameter `parent_index` is the full index of `arrays` within the - nested lists passed to _block_check_depths_match at the top of the - recursion. - The return value is a pair. The first item returned is the full index - of an element (specifically the first element) from the bottom of the - nesting in `arrays`. An empty list at the bottom of the nesting is - represented by a `None` index. - The second item is the maximum of the ndims of the arrays nested in - `arrays`. + Parameters + ---------- + arrays : nested list of arrays + The arrays to check + parent_index : list of int + The full index of `arrays` within the nested lists passed to + `_block_check_depths_match` at the top of the recursion. + + Returns + ------- + first_index : list of int + The full index of an element from the bottom of the nesting in + `arrays`. If any element at the bottom is an empty list, this will + refer to it, and the last index along the empty axis will be `None`. + max_arr_ndim : int + The maximum of the ndims of the arrays nested in `arrays`. """ - def format_index(index): - idx_str = ''.join('[{}]'.format(i) for i in index if i is not None) - return 'arrays' + idx_str if type(arrays) is tuple: # not strictly necessary, but saves us from: # - more than one way to do things - no point treating tuples like @@ -394,7 +406,7 @@ def _block_check_depths_match(arrays, parent_index=[]): '{} is a tuple. ' 'Only lists can be used to arrange blocks, and np.block does ' 'not allow implicit conversion from tuple to ndarray.'.format( - format_index(parent_index) + _block_format_index(parent_index) ) ) elif type(arrays) is list and len(arrays) > 0: @@ -411,9 +423,12 @@ def _block_check_depths_match(arrays, parent_index=[]): "{}, but there is an element at depth {} ({})".format( len(first_index), len(index), - format_index(index) + _block_format_index(index) ) ) + # propagate our flag that indicates an empty list at the bottom + if index[-1] is None: + first_index = index return first_index, max_arr_ndim elif type(arrays) is list and len(arrays) == 0: # We've 'bottomed out' on an empty list @@ -439,8 +454,6 @@ def _block(arrays, max_depth, result_ndim): @recursive def block_recursion(self, arrays, depth=0): if depth < max_depth: - if len(arrays) == 0: - raise ValueError('Lists cannot be empty') arrs = [self(arr, depth+1) for arr in arrays] return _nx.concatenate(arrs, axis=-(max_depth-depth)) else: @@ -601,4 +614,10 @@ def block(arrays): """ bottom_index, arr_ndim = _block_check_depths_match(arrays) list_ndim = len(bottom_index) + if bottom_index and bottom_index[-1] is None: + raise ValueError( + 'List at {} cannot be empty'.format( + _block_format_index(bottom_index) + ) + ) return _block(arrays, list_ndim, max(arr_ndim, list_ndim)) |