29

In Python, is it possible to write a function that returns the dimensions of a multidimensional array (given the assumption that the array's dimensions are not jagged)?

For example, the dimensions of [[2,3], [4,2], [3,2]] would be [3, 2], while the dimensions of [[[3,2], [4,5]],[[3,4],[2,3]]] would be [2,2,2].

Does Python have any built-in functions that will return all of the dimensions of a multidimensional array, or will I need to implement this function myself?

Anderson Green
  • 30,230
  • 67
  • 195
  • 328
  • 3
    isn't the second example [2, 2, 2] ? – DRC Jul 08 '13 at 16:44
  • 3
    Out of curiosity, what would it do on `[[1,2],[3,4,5]]`? Or `[[1,2],[3,4],[5,[6,7]]]`? – Wrikken Jul 08 '13 at 16:44
  • 1
    @Wrikken I'm working with the assumption that the input array will not be jagged. I'd want to check the regularity of the array's dimensions first, and then throw an error if the array is jagged. – Anderson Green Jul 08 '13 at 16:48
  • 3
    Unclear why this is marked as a duplicate: the "duplicate" is about numpy arrays and this is about Python lists. The answers there do not help the OP. – eric Oct 20 '19 at 03:13

6 Answers6

46

No, there's nothing built-in because with such "arrays"1 it can be jagged and the concept of "dimensions" or "shape" doesn't make any sense at all. So, you'll have to write your own. If you can make an assumption of uniformity along all dimensions, you can proceed as follows:

dim1 = len(a)
dim2 = len(a[0])
dim3 = len(a[0][0])
.
.
.

It'd be pretty easy to make this recursive to handle all dimensions. This should do it:

def dim(a):
    if not type(a) == list:
        return []
    return [len(a)] + dim(a[0])

But if you need something like this, you might want to consider looking at NumPy arrays which have numpy.ndarray.shape which would give you what you're looking for.

from numpy import array
l = [[2, 3], [4, 2], [3, 2]]
a = array(l)
print a.shape

Output

(3, 2)

1 In scare quotes because you're not really looking at array, you're looking at a list, or a list of lists, or a list of list of lists....

jason
  • 236,483
  • 35
  • 423
  • 525
  • 1
    " the concept of "dimensions" or "shape" doesn't make any sense at all" Not sure why you would say this? It makes a lot of sense and your answer makes this clear. Numpy handles this kind of thing gracefully, though obviously it isn't the exact same. Seems shape should be added as an attribute frankly (the jagged case could just return an error). – eric Oct 20 '19 at 03:12
  • Python should have a function for this. – user2585501 Jan 08 '22 at 02:43
17

You can do it with numpy:

import numpy
l = [[2,3], [4,2], [3,2]]
m = numpy.array(l)
print m.shape

But the shape of your second example is [2,2,2], not [1,4,5], unless I've misunderstood your question...

Ben
  • 66,838
  • 37
  • 84
  • 108
7

That is not a multi-dimensional array. It is a list. It happens to contain other lists. There's nothing to say that your list could not be:

[[2,3], [4,2], [3,2,4,5,6]]

In which case, what value would you expect such a function to return?

There is no general function that does what you ask, not least because Python itself does not define a matrix/array class. You certainly can write your own function which operates on iterable objects like lists and tuples if you are prepared to make assumptions, or write assertions, as to the uniformity of the list. Use len(a) for the first dimension, len(a[0]) for the second, and so on. Recursion will be your friend here.

If you used a numpy array for your matrix, which to be honest would make a lot of sense, then your function would exist (it is the shape property of the ndarray class) and be meaningful.

David Heffernan
  • 601,492
  • 42
  • 1,072
  • 1,490
  • Is there any difference between arrays and lists in Python? I thought they were synonymous. – Anderson Green Jul 08 '13 at 16:46
  • OF course it would've been more constructive to assume that the OP's data does in fact have a regular shape and provide something else than a non-answer. Or ask for clarification instead of assuming. – millimoose Jul 08 '13 at 16:47
  • @AndersonGreen Python does not have arrays. It has lists and tuples. But no arrays. – David Heffernan Jul 08 '13 at 16:47
  • 1
    @millimoose I did not assume anything about OP's data. I was trying to explain why the designers of Python could not write such a general purpose function because they could not make such assumptions. – David Heffernan Jul 08 '13 at 16:48
  • @DavidHeffernan: well, the stdlib has a type called `array` (`from array import array`), although I admit it's not used that much. – DSM Jul 08 '13 at 16:49
  • @AndersonGreen More to the point, Python does not have (or does not commonly use) fixed-size blocks of memory you can access using a possibly multidimensional index. Lists certainly use resizeable arrays "behind the scenes". – millimoose Jul 08 '13 at 16:49
  • 1
    @DavidHeffernan I missed the bit in the OP's question where they ask about built-in functions specifically, since they start with "Is it possible to write...". You're right in that it doesn't make sense to provide such a function built-in since it would need to consider the case where the data is irregular and such genericity is too much bother for too little benefit. (Over using a library that deals with this.) – millimoose Jul 08 '13 at 16:53
5

Assuming the input array is not jagged :

def arr_dimen(a):
  return [len(a)]+arr_dimen(a[0]) if(type(a) == list) else []
Archit Jain
  • 2,154
  • 1
  • 18
  • 32
1
import numpy as np
# define array 3 row and 5 colums
a = np.arange(15).reshape(3, 5)
print ("the array elements:\n",a);
# print all dim 
print("all dim :\n",a.shape)
# the print the number of row only
print("the number of rows :\n",a.shape[0])
# the print the number of colume only
print("the number of cols :\n",a.shape[1])

enter image description here

RiveN
  • 2,595
  • 11
  • 13
  • 26
1

Iterative approach

a = [[[3,2], [4,5]],[[3,4],[2,3]]]
shape = []
b = a
while type(b) == list:
    shape.append(len(b))
    b = b[0]
print(shape)