diff options
author | Eric Wieser <wieser.eric@gmail.com> | 2018-07-22 15:02:53 +0100 |
---|---|---|
committer | Eric Wieser <wieser.eric@gmail.com> | 2018-07-22 18:47:31 +0100 |
commit | c9ffde629b0f10255714b84fe75681c7f9fc4251 (patch) | |
tree | 4711620edb4db433db999be86b7768991a79ac5e /numpy | |
parent | 486a764c08c24ccba0d4baad901378112a9eec88 (diff) | |
download | numpy-c9ffde629b0f10255714b84fe75681c7f9fc4251.tar.gz |
BUG: Make np.array([[1], 2]) and np.array([1, [2]]) behave in the same way
Diffstat (limited to 'numpy')
-rw-r--r-- | numpy/core/src/multiarray/ctors.c | 40 | ||||
-rw-r--r-- | numpy/core/tests/test_multiarray.py | 13 |
2 files changed, 34 insertions, 19 deletions
diff --git a/numpy/core/src/multiarray/ctors.c b/numpy/core/src/multiarray/ctors.c index 4602245de..938850997 100644 --- a/numpy/core/src/multiarray/ctors.c +++ b/numpy/core/src/multiarray/ctors.c @@ -845,46 +845,48 @@ discover_dimensions(PyObject *obj, int *maxndim, npy_intp *d, int check_it, return 0; } else { - int maxndim_m1 = *maxndim - 1; - PyObject *first = PySequence_Fast_GET_ITEM(seq, 0); + int all_elems_maxndim = *maxndim - 1; + npy_intp *all_elems_d = d + 1; + int all_dimensions_match = 1; + /* Get the dimensions of the first item as a baseline */ + PyObject *first = PySequence_Fast_GET_ITEM(seq, 0); if (discover_dimensions( - first, &maxndim_m1, d + 1, check_it, + first, &all_elems_maxndim, all_elems_d, check_it, stop_at_string, stop_at_tuple, out_is_object) < 0) { Py_DECREF(seq); return -1; } - /* For the dimension truncation check below */ - *maxndim = maxndim_m1 + 1; + /* Compare the dimensions of all the remaining items */ for (i = 1; i < n; ++i) { int j; - npy_intp dtmp[NPY_MAXDIMS]; - PyObject *elem = PySequence_Fast_GET_ITEM(seq, i); + int elem_maxndim = *maxndim - 1; + npy_intp elem_d[NPY_MAXDIMS]; - /* Get the dimensions of the remaining items */ + PyObject *elem = PySequence_Fast_GET_ITEM(seq, i); if (discover_dimensions( - elem, &maxndim_m1, dtmp, check_it, + elem, &elem_maxndim, elem_d, check_it, stop_at_string, stop_at_tuple, out_is_object) < 0) { Py_DECREF(seq); return -1; } - /* Reduce max_ndim_m1 to just items which match */ - for (j = 0; j < maxndim_m1; ++j) { - if (dtmp[j] != d[j+1]) { - maxndim_m1 = j; + /* Find the number of left-dimensions which match, j */ + for (j = 0; j < elem_maxndim && j < all_elems_maxndim; ++j) { + if (elem_d[j] != all_elems_d[j]) { break; } } + if (j != elem_maxndim || j != all_elems_maxndim) { + all_dimensions_match = 0; + } + all_elems_maxndim = j; } - /* - * If the dimensions are truncated, need to produce - * an object array. - */ - if (maxndim_m1 + 1 < *maxndim) { + *maxndim = all_elems_maxndim + 1; + if (!all_dimensions_match) { + /* typically results in an array containing variable-length lists */ *out_is_object = 1; - *maxndim = maxndim_m1 + 1; } } diff --git a/numpy/core/tests/test_multiarray.py b/numpy/core/tests/test_multiarray.py index e85a73154..07d1361d6 100644 --- a/numpy/core/tests/test_multiarray.py +++ b/numpy/core/tests/test_multiarray.py @@ -903,6 +903,19 @@ class TestCreation(object): assert_raises(ValueError, np.ndarray, buffer=buf, strides=(0,), shape=(max_bytes//itemsize + 1,), dtype=dtype) + def test_jagged_ndim_object(self): + # Lists of mismatching depths are treated as object arrays + a = np.array([[1], 2, 3]) + assert_equal(a.shape, (3,)) + assert_equal(a.dtype, object) + + a = np.array([1, [2], 3]) + assert_equal(a.shape, (3,)) + assert_equal(a.dtype, object) + + a = np.array([1, 2, [3]]) + assert_equal(a.shape, (3,)) + assert_equal(a.dtype, object) class TestStructured(object): def test_subarray_field_access(self): |