This is a bit like converting numbers from a base of numbers of various sizes into a standard integer. In base 10, you can have five digits, each of which is from 0 to 9, and then you converted them into a single whole using i = a*10000 + b*1000 + c*100 + d*10 + e*1 .
Equivalently, for decimal conversion you can write i = np.dot([a, b, c, d, e], bases) , where bases = [10*10*10*10, 10*10*10, 10*10, 10, 1] .
You can do the same with your bases, except that your positions are entered by factors [3, 3, 2, 2, 3] instead of [10, 10, 10, 10, 10]. Therefore, you can set bases = [3*2*2*3, 2*2*3, 2*3, 3, 1] (= [36, 12, 6, 3, 1]), and then use i = np.dot([a, b, c, d, e], bases) . Please note that this will always give answers in the range from 0 to 107 if a, b, c, d and e fall into the ranges you specify.
To convert i back to a list of numbers, you can use something like this:
digits = [] remainder = i for base in bases: digit, remainder = divmod(remainder, base) digits.append(digit)
On the other hand, to keep your life simple, you are probably better off using Paul Panzer's answer, which pretty much does the same. (I never thought of an n-digit number like the coordinates of a cell in an n-dimensional grid before, but it turns out that they are mathematically equivalent. And np.ravel is an easy way to assign a serial number to each cell.)