3

given a list of non-zero integers like, [2, 3, 4, 2]

generate a list of all the permutations possible where each element above reflects its maximum variance (I am sure there is a better way to express this, but I don't have the math background); each element in the above array can be considered a dimension; the above 2 would allow for values 0 and 1; the 3 would allow for values 0, 1 and 2, etc

the result would be a list of zero-based tuples:

[(0, 0, 0, 0), (0, 0, 0, 1), (0, 0, 1, 0), (0, 0, 1, 1), (0, 0, 2, 0)... 

and so on till (1, 2, 3, 1)]

the length of the array could vary, from 1 element to x

5
  • This is definitely not a duplicate, this is a completely different question that's not really related to permutations at all. Commented Jul 3, 2019 at 12:23
  • Perhaps it may help to clarify the expected input and output with a smaller tuple? To me, it looks like counting, but with extra steps. Commented Jul 3, 2019 at 12:25
  • 3
    Those are not permutations, but a product. Commented Jul 3, 2019 at 12:32
  • Thanks for correcting my description. It really is counting, but in different base systems. I was thinking "permutations" because the problem I am trying to solve relates to product configurations, e.g. 6 different colors, 4 different thicknesses, 2 different substrates, etc. Commented Jul 3, 2019 at 13:35
  • I disagree with the duplicate marking. Much more importantly, the referenced page doesn't even come remotely close to the elegance of Adam.Er8's answer. Commented Jul 4, 2019 at 19:48

3 Answers 3

3

you can use itertools.product:

try this:

from itertools import product limits = [2, 3, 4, 2] result = list(product(*[range(x) for x in limits])) print(result) 
Sign up to request clarification or add additional context in comments.

3 Comments

Or result = list(product(*map(range, limits)))
perhaps range(x + 1) for having the extrema included?
In the original question he added "and so on till (1, 2, 3, 1)]", so no +1 needed.
0

What you're basically doing is trying to represent integers in a changing base. In your example, some of the digits are base 2, some base 3, and some base 4. So you can use an algorithm that chance base 10 to any base, and have the base you convert to depend on the current digit. Here's what I threw together, not sure if it's completely clear how it works.

n = [2, 3, 4, 2] max_val = 1 for i in n: max_val *= i ans = [] # will hold the generated lists for i in range(max_val): current_value = i current_perm = [] for j in n[::-1]: # For you, the 'least significant bit' is on the right current_perm.append(current_value % j) current_value //= j # integer division in python 3 ans.append(current_perm[::-1]) # flip it back around! print(ans) 

Comments

0

So you basically just want to count, but you have a different limit for each position?

limits = [2,3,4,2] counter = [0] * len(limits) def check_limits(): for i in range(len(limits)-1, 0, -1): if counter[i] >= limits[i]: counter[i] = 0 counter[i-1] += 1 return not counter[0] >= limits[0] while True: counter[len(counter)-1] += 1 check = check_limits() if check: print(counter) else: break 

Not a list of tuples, but you get the idea...

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.