Python: Generating all arrays of n-length value combinations within a range

Ok I am looking for the smartest and most compact way to perform this function.

def f(): [[a,b,c] for a in range(6) for b in range(6) for c in range(6)] 

which should generate all combinations for values ​​a, b, c as follows:

 [0,0,0] [0,0,1] [0,0,2] ... [1,0,0] [1,0,1] ... 

etc.

But I want this to be flexible, so I can change the range or iterable, as well as the length of the generated arrays. Range is easy:

 def f(min, max): [[a,b,c] for a in range(min,max) for b in range(min,max) for c in range(min,max)] 

This is normal for arrays with 3 lengths, but now I'm thinking of creating arrays of 4 lengths or arrays of 7 lengths and generating all combinations for them in the same range.

It should exist in a simple way, perhaps with the concatenation of arrays or nesting understanding lists to some extent, but my decisions seem too complicated.

Sorry for such a long post.

+5
source share
5 answers

You can use itertools.product , which is just a convenient feature for nested iterations. It also has a repeat argument if you want to repeat the same iterable several times:

 >>> from itertools import product >>> amin = 0 >>> amax = 2 >>> list(product(range(amin, amax), repeat=3)) [(0, 0, 0), (0, 0, 1), (0, 1, 0), (0, 1, 1), (1, 0, 0), (1, 0, 1), (1, 1, 0), (1, 1, 1)] 

To get list of list , you can use map :

 >>> list(map(list, product(range(amin, amax), repeat=3))) [[0, 0, 0], [0, 0, 1], [0, 1, 0], [0, 1, 1], [1, 0, 0], [1, 0, 1], [1, 1, 0], [1, 1, 1]] 

However, product is an iterator, so it is really efficient if you just iterate over it and not send it to list . At least if possible in your program. For instance:

 >>> for prod in product(range(amin, amax), repeat=3): ... print(prod) # one example (0, 0, 0) (0, 0, 1) (0, 1, 0) (0, 1, 1) (1, 0, 0) (1, 0, 1) (1, 1, 0) (1, 1, 1) 
+3
source

You can use itertools.product :

 from itertools import product def f(mn, mx, n): return list(product(*[range(mn, mx)]*n))) 

Drop list to return a generator for memory efficiency.

+6
source

Itertools has everything you need. combination_with_replacement will generate combinations of a given length with repeating elements from a given iterable. Note that the return value will be an iterator.

 def f(min, max, num): return itertools.combinations_with_replacement(range(min, max), num) 
+1
source

Pure python implementation:

 k=2 # k-uples xmin=2 xmax=5 n=xmax-xmin l1 = [x for x in range(n**k)] l2 = [[ x//n**(kj-1)%n for x in l1] for j in range(k)] l3 = [[ xmin + l2[i][j] for i in range(k)] for j in range(n**k)] 

l3 :

 [[2 2] [2 3] [2 4] [3 2] [3 3] [3 4] [4 2] [4 3] [4 4]] 
+1
source

What you are looking for is a Cartesian product of ranges. Fortunately, this already exists in itertools

 import itertools print(list(itertools.product(range(0,5), range(0,5), range(0,5)))) 
-1
source

Source: https://habr.com/ru/post/1264507/


All Articles