1

I have a function f([i_0, i_1, ..., i_k-1]) which takes as input a k-dimensional array of integers and returns some object.

Given the range for each index (as a two-dimensional array ranges=[i_0_range, i_1_range, ...]), how do I generate a k-dimensional list / array containing objects evaluated for each value of indices?

If k was fixed, I'd simply do k nested loops. But I would like to have a solution working for any k. How can I do this in Python?

2
  • What have you tried? What was the result? What did you expect? You say you have a function, please share the code. Commented Nov 4, 2020 at 23:30
  • I have no idea what to try :( I was thinking about some sort of recursive / dynamic solution. Note that the particular form of the function is not relevant to my question. Commented Nov 4, 2020 at 23:38

1 Answer 1

2

You can use itertools.product to generate all the different combinations of indexes from the ranges. You can then iterate over the tuples produced by that iterator, calling f for each tuple. For example, if f is defined to return a string of the input indexes:

import itertools

def f(indexes):
    return ','.join(map(str, indexes))
    
ranges = [range(0, 2), range(1, 3), range(2, 4)]

objs = [f(list(t)) for t in itertools.product(*ranges)]
print(objs)

Output:

['0,1,2', '0,1,3', '0,2,2', '0,2,3', '1,1,2', '1,1,3', '1,2,2', '1,2,3']

Note that dependent on your implementation of f, it might not be necessary to convert the returned tuple from itertools.product to a list and you could just use f(t) instead of f(list(t)).

Sign up to request clarification or add additional context in comments.

2 Comments

Thanks a lot!! Seems to do the job. Could you please elaborate what itertools.product(*ranges) does, and why you called f with [*t] argument? (Sorry, apparently I'm not familiar with these Python basics.)
*ranges flattens the ranges array, so that each element is passed separately to itertools.product, which then creates the cartesian product of each of the ranges. Note that I changed the code to be f(list(t)) for t in itertools.product(*ranges) so that it would correctly deal with k greater than 2; itertools.product returns a tuple of values (for i_0, i_1, ..., i_k), list(t) then converts that into a list as described in your question. Dependent on your implementation of f, it might not be necessary to convert to a list and you could just use f(t)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.