(3,) does not mean the 3 is first. It is simply the Python way of writing a 1-element tuple. If the shape were a list instead, it would be [3].

(, 3) is not valid Python. The syntax for a 1-element tuple is (element,).

The reason it can't be just (3) is that Python simply views the parentheses as a grouping construct, meaning (3) is interpreted as 3, an integer.

Answer from iz_ on Stack Overflow
🌐
W3Schools
w3schools.com β€Ί python β€Ί numpy β€Ί numpy_array_shape.asp
NumPy Array Shape
NumPy arrays have an attribute called shape that returns a tuple with each index having the number of corresponding elements. ... The example above returns (2, 4), which means that the array has 2 dimensions, where the first dimension has 2 ...
🌐
NumPy
numpy.org β€Ί doc β€Ί stable β€Ί reference β€Ί generated β€Ί numpy.shape.html
numpy.shape β€” NumPy v2.5 Manual
Equivalent array method. ... Try it in your browser! >>> import numpy as np >>> np.shape(np.eye(3)) (3, 3) >>> np.shape([[1, 3]]) (1, 2) >>> np.shape([0]) (1,) >>> np.shape(0) ()
Discussions

python - Shape 1 of numpy array - Stack Overflow
There are two issues - the proper notation for a tuple (shape is a tuple), and what does it mean to be 1 dimensional. People coming from MATLAB, and some linear algebra, backgrounds, can't conceive of an array that only has 1 dimension. It has to be a row vector or column vector, never a plain ... More on stackoverflow.com
🌐 stackoverflow.com
python - Difference between numpy.array shape (R, 1) and (R,) - Stack Overflow
In numpy, some of the operations return in shape (R, 1) but some return (R,). This will make matrix multiplication more tedious since explicit reshape is required. For example, given a matrix M, if... More on stackoverflow.com
🌐 stackoverflow.com
what's the difference between a numpy array with shape (x,) and (x, 1)?
import numpy as np arr = np.array([1, 2, 3, 4, 5]) print(arr.shape) # Output: (5,) arr = np.array([[1], [2], [3], [4], [5]]) print(arr.shape) # Output: (5, 1) arr = np.array([[1, 2, 3, 4, 5]]) print(arr.shape) # Output: (1, 5) More on reddit.com
🌐 r/learnpython
6
1
October 6, 2023
Numpy: What's the point of producing arrays of shape (N,) instead of (N,1)? Super annoying feature.
I don't have a good answer for you, I share your frustration. I do have a couple tips that might help sometimes. Numpy's newaxis is an alias for None, so you can quickly expand dimensions with X[:, None] or X[None, :] (etc.) Also, you can pass keepdims=True as an argument to many numpy functions to produce an array that broadcasts properly. More on reddit.com
🌐 r/learnpython
12
3
August 29, 2020
🌐
GeeksforGeeks
geeksforgeeks.org β€Ί python β€Ί numpy-array-shape
NumPy Array Shape - GeeksforGeeks
July 15, 2025 - The shape of each array is printed, revealing their dimensions and sizes along each dimension. ... import numpy as npy # creating a 2-d array arr1 = npy.array([[1, 3, 5, 7], [2, 4, 6, 8]]) # creating a 3-d array arr2 = npy.array([[[1, 2], [3, 4]], [[5, 6], [7, 8]]]) print(arr1.shape) print(arr2.shape)
🌐
NumPy
numpy.org β€Ί devdocs β€Ί reference β€Ί generated β€Ί numpy.shape.html
numpy.shape β€” NumPy v2.6.dev0 Manual
Equivalent array method. ... Try it in your browser! >>> import numpy as np >>> np.shape(np.eye(3)) (3, 3) >>> np.shape([[1, 3]]) (1, 2) >>> np.shape([0]) (1,) >>> np.shape(0) ()
🌐
Python Guides
pythonguides.com β€Ί python-numpy-shape
NumPy Shape in Python: shape[0] and shape[1]
May 8, 2025 - That is worth keeping straight when you move on to 3D arrays in NumPy. This is the part that sends people to search engines. For a 2D array, shape[0] is the number of rows and shape[1] is the number of columns:
🌐
NumPy
numpy.org β€Ί doc β€Ί stable β€Ί reference β€Ί generated β€Ί numpy.ndarray.shape.html
numpy.ndarray.shape β€” NumPy v2.5 Manual
The shape property is usually used ... As with numpy.reshape, one of the new shape dimensions can be -1, in which case its value is inferred from the size of the array and the remaining dimensions....
Find elsewhere
🌐
NumPy
numpy.org β€Ί doc β€Ί 2.2 β€Ί reference β€Ί generated β€Ί numpy.ndarray.shape.html
numpy.ndarray.shape β€” NumPy v2.2 Manual
The shape property is usually used ... As with numpy.reshape, one of the new shape dimensions can be -1, in which case its value is inferred from the size of the array and the remaining dimensions....
🌐
Note.nkmk.me
note.nkmk.me β€Ί home β€Ί python β€Ί numpy
NumPy: Get the dimensions, shape, and size of an array | note.nkmk.me
April 23, 2025 - You can get the number of dimensions, the shape (length of each dimension), and the size (total number of elements) of a NumPy array (numpy.ndarray) using the ndim, shape, and size attributes. The built-in len() function returns the size of the first dimension. ... Use the following one- to three-dimensional arrays as examples. import numpy as np a_1d = np.arange(3) print(a_1d) # [0 1 2] a_2d = np.arange(12).reshape((3, 4)) print(a_2d) # [[ 0 1 2 3] # [ 4 5 6 7] # [ 8 9 10 11]] a_3d = np.arange(24).reshape((2, 3, 4)) print(a_3d) # [[[ 0 1 2 3] # [ 4 5 6 7] # [ 8 9 10 11]] # # [[12 13 14 15] # [16 17 18 19] # [20 21 22 23]]]
🌐
NumPy
numpy.org β€Ί devdocs β€Ί reference β€Ί generated β€Ί numpy.ndarray.shape.html
numpy.ndarray.shape β€” NumPy v2.6.dev0 Manual
The shape property is usually used ... As with numpy.reshape, one of the new shape dimensions can be -1, in which case its value is inferred from the size of the array and the remaining dimensions....
Top answer
1 of 8
735

1. The meaning of shapes in NumPy

You write, "I know literally it's list of numbers and list of lists where all list contains only a number" but that's a bit of an unhelpful way to think about it.

The best way to think about NumPy arrays is that they consist of two parts, a data buffer which is just a block of raw elements, and a view which describes how to interpret the data buffer.

For example, if we create an array of 12 integers:

>>> a = numpy.arange(12)
>>> a
array([ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11])

Then a consists of a data buffer, arranged something like this:

β”Œβ”€β”€β”€β”€β”¬β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”
β”‚  0 β”‚  1 β”‚  2 β”‚  3 β”‚  4 β”‚  5 β”‚  6 β”‚  7 β”‚  8 β”‚  9 β”‚ 10 β”‚ 11 β”‚
β””β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”˜

and a view which describes how to interpret the data:

>>> a.flags
  C_CONTIGUOUS : True
  F_CONTIGUOUS : True
  OWNDATA : True
  WRITEABLE : True
  ALIGNED : True
  UPDATEIFCOPY : False
>>> a.dtype
dtype('int64')
>>> a.itemsize
8
>>> a.strides
(8,)
>>> a.shape
(12,)

Here the shape (12,) means the array is indexed by a single index which runs from 0 to 11. Conceptually, if we label this single index i, the array a looks like this:

i= 0    1    2    3    4    5    6    7    8    9   10   11
β”Œβ”€β”€β”€β”€β”¬β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”
β”‚  0 β”‚  1 β”‚  2 β”‚  3 β”‚  4 β”‚  5 β”‚  6 β”‚  7 β”‚  8 β”‚  9 β”‚ 10 β”‚ 11 β”‚
β””β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”˜

If we reshape an array, this doesn't change the data buffer. Instead, it creates a new view that describes a different way to interpret the data. So after:

>>> b = a.reshape((3, 4))

the array b has the same data buffer as a, but now it is indexed by two indices which run from 0 to 2 and 0 to 3 respectively. If we label the two indices i and j, the array b looks like this:

i= 0    0    0    0    1    1    1    1    2    2    2    2
j= 0    1    2    3    0    1    2    3    0    1    2    3
β”Œβ”€β”€β”€β”€β”¬β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”
β”‚  0 β”‚  1 β”‚  2 β”‚  3 β”‚  4 β”‚  5 β”‚  6 β”‚  7 β”‚  8 β”‚  9 β”‚ 10 β”‚ 11 β”‚
β””β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”˜

which means that:

>>> b[2,1]
9

You can see that the second index changes quickly and the first index changes slowly. If you prefer this to be the other way round, you can specify the order parameter:

>>> c = a.reshape((3, 4), order='F')

which results in an array indexed like this:

i= 0    1    2    0    1    2    0    1    2    0    1    2
j= 0    0    0    1    1    1    2    2    2    3    3    3
β”Œβ”€β”€β”€β”€β”¬β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”
β”‚  0 β”‚  1 β”‚  2 β”‚  3 β”‚  4 β”‚  5 β”‚  6 β”‚  7 β”‚  8 β”‚  9 β”‚ 10 β”‚ 11 β”‚
β””β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”˜

which means that:

>>> c[2,1]
5

It should now be clear what it means for an array to have a shape with one or more dimensions of size 1. After:

>>> d = a.reshape((12, 1))

the array d is indexed by two indices, the first of which runs from 0 to 11, and the second index is always 0:

i= 0    1    2    3    4    5    6    7    8    9   10   11
j= 0    0    0    0    0    0    0    0    0    0    0    0
β”Œβ”€β”€β”€β”€β”¬β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”
β”‚  0 β”‚  1 β”‚  2 β”‚  3 β”‚  4 β”‚  5 β”‚  6 β”‚  7 β”‚  8 β”‚  9 β”‚ 10 β”‚ 11 β”‚
β””β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”˜

and so:

>>> d[10,0]
10

A dimension of length 1 is "free" (in some sense), so there's nothing stopping you from going to town:

>>> e = a.reshape((1, 2, 1, 6, 1))

giving an array indexed like this:

i= 0    0    0    0    0    0    0    0    0    0    0    0
j= 0    0    0    0    0    0    1    1    1    1    1    1
k= 0    0    0    0    0    0    0    0    0    0    0    0
l= 0    1    2    3    4    5    0    1    2    3    4    5
m= 0    0    0    0    0    0    0    0    0    0    0    0
β”Œβ”€β”€β”€β”€β”¬β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”
β”‚  0 β”‚  1 β”‚  2 β”‚  3 β”‚  4 β”‚  5 β”‚  6 β”‚  7 β”‚  8 β”‚  9 β”‚ 10 β”‚ 11 β”‚
β””β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”˜

and so:

>>> e[0,1,0,0,0]
6

See the NumPy internals documentation for more details about how arrays are implemented.

2. What to do?

Since numpy.reshape just creates a new view, you shouldn't be scared about using it whenever necessary. It's the right tool to use when you want to index an array in a different way.

However, in a long computation it's usually possible to arrange to construct arrays with the "right" shape in the first place, and so minimize the number of reshapes and transposes. But without seeing the actual context that led to the need for a reshape, it's hard to say what should be changed.

The example in your question is:

numpy.dot(M[:,0], numpy.ones((1, R)))

but this is not realistic. First, this expression:

M[:,0].sum()

computes the result more simply. Second, is there really something special about column 0? Perhaps what you actually need is:

M.sum(axis=0)
2 of 8
31

The difference between (R,) and (1,R) is literally the number of indices that you need to use. ones((1,R)) is a 2-D array that happens to have only one row. ones(R) is a vector. Generally if it doesn't make sense for the variable to have more than one row/column, you should be using a vector, not a matrix with a singleton dimension.

For your specific case, there are a couple of options:

1) Just make the second argument a vector. The following works fine:

    np.dot(M[:,0], np.ones(R))

2) If you want matlab like matrix operations, use the class matrix instead of ndarray. All matricies are forced into being 2-D arrays, and operator * does matrix multiplication instead of element-wise (so you don't need dot). In my experience, this is more trouble that it is worth, but it may be nice if you are used to matlab.

🌐
NumPy
numpy.org β€Ί doc β€Ί 2.3 β€Ί reference β€Ί generated β€Ί numpy.shape.html
numpy.shape β€” NumPy v2.3 Manual
Equivalent array method. ... Try it in your browser! >>> import numpy as np >>> np.shape(np.eye(3)) (3, 3) >>> np.shape([[1, 3]]) (1, 2) >>> np.shape([0]) (1,) >>> np.shape(0) ()
🌐
NumPy
numpy.org β€Ί doc β€Ί 2.2 β€Ί reference β€Ί generated β€Ί numpy.shape.html
numpy.shape β€” NumPy v2.2 Manual
Equivalent array method. ... >>> import numpy as np >>> np.shape(np.eye(3)) (3, 3) >>> np.shape([[1, 3]]) (1, 2) >>> np.shape([0]) (1,) >>> np.shape(0) ()
🌐
GeeksforGeeks
geeksforgeeks.org β€Ί python β€Ί difference-between-numpy-array-shape-r-1-and-r
Difference between numpy.array shape (R, 1) and (R,) - GeeksforGeeks
July 23, 2025 - Since a 1-D array only has one row, the number of rows is not shown in the shape tuple. Example: In the given example, we have created a one-dimensional array consisting of 5 elements.
🌐
TutorialsPoint
tutorialspoint.com β€Ί numpy β€Ί numpy_array_shape.htm
NumPy - Array Shape
The shape of a NumPy array is a tuple of integers. Each integer in the tuple represents the size of the array along a particular dimension or axis. For example, an array with shape (3, 4) has 3 rows and 4 columns.
🌐
Reddit
reddit.com β€Ί r/learnpython β€Ί what's the difference between a numpy array with shape (x,) and (x, 1)?
r/learnpython on Reddit: what's the difference between a numpy array with shape (x,) and (x, 1)?
October 6, 2023 -

hey, im doing an ai thing in school and my code didnt work as expected, and after 5 hours i found out i reshaped an array from (206,) to (206,1) and that made the results wrong. and from what i understand, the shape means the length of each dimension, and length is not 0 indexed so a size of 1 would be equal to just 1D no?

🌐
Medium
medium.com β€Ί @amit25173 β€Ί understanding-numpy-shape-6fbb6b83891e
Understanding numpy.shape. If you think you need to spend $2,000… | by Amit Yadav | Medium
February 9, 2025 - For a 1D array, the shape might look like (n,), where n is the number of elements. For a 3D array, it could look like (x, y, z), representing depth, rows, and columns. Here’s another quick example to make it more fun.
🌐
Programiz
programiz.com β€Ί python-programming β€Ί numpy β€Ί methods β€Ί shape
NumPy shape() | Programiz
August 30, 2023 - The shape() method returns the shape of an array as a tuple. import numpy as np # create 1D and 2D arrays array1 = np.array([0, 1, 2, 3]) array2 = np.array([[8, 9]]) # shape of array1 shape1 = np.shape(array1) print('Shape of the first array ...
🌐
NumPy
numpy.org β€Ί doc β€Ί 2.4 β€Ί reference β€Ί generated β€Ί numpy.shape.html
numpy.shape β€” NumPy v2.4 Manual
Equivalent array method. ... Try it in your browser! >>> import numpy as np >>> np.shape(np.eye(3)) (3, 3) >>> np.shape([[1, 3]]) (1, 2) >>> np.shape([0]) (1,) >>> np.shape(0) ()
🌐
Interactive Chaos
interactivechaos.com β€Ί en β€Ί python β€Ί function β€Ί ndarrayshape
ndarray.shape | Interactive Chaos
The numpy.ndarray.shape attribute ... one of the dimensions sizes can be -1, in which case the size of that dimension is inferred from the number of elements in the array and the size of the other dimensions....