Python:生成范围内值的所有n长度数组合

时间:2022-12-10 18:22:28

Ok. I'm looking for the smartest and more compact way to do 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 the combinations for the values a,b,c like this:

这应该生成值a,b,c的所有组合,如下所示:

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

and so on...

等等...

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

但我希望这是灵活的,所以我可以改变范围或可迭代,以及生成的数组的长度。范围很简单:

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 ok for 3-length arrays, but I'm thinking now of making 4-length arrays or 7-length arrays and generate all combinations for them in the same range.

对于3长度数组来说这是可以的,但我现在考虑制作4长度数组或7长度数组,并在相同范围内为它们生成所有组合。

It has to exist an easy way, maybe with concatenating arrays or nesting comprehension lists in some way, but my solutions seem to bee too much complex.

它必须以一种简单的方式存在,可能以某种方式连接数组或嵌套理解列表,但我的解决方案似乎过于复杂。

Sorry for such a long post.

对不起这么长的帖子。

5 个解决方案

#1


4  

You can use itertools.product which is just a convenience function for nested iterations. It also has a repeat-argument if you want to repeat the same iterable multiple times:

您可以使用itertools.product,它只是嵌套迭代的便利函数。如果你想多次重复相同的迭代,它也有一个repeat参数:

>>> 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 the list of list you could use map:

要获取列表列表,您可以使用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's really efficient if you just iterate over it instead of casting it to a list. At least if that's possible in your program. For example:

但是,产品是一个迭代器,所以如果你只是迭代它而不是将它转换为列表,它真的很有效。至少如果你的程序可以做到这一点。例如:

>>> 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)

#2


6  

You can use itertools.product:

您可以使用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.

删除列表,返回生成器以提高内存效率。

#3


1  

itertools has everything you need. combinations_with_replacement will generate combinations of given length with repeating elements from given iterable. Note that returned value will be iterator.

itertools拥有您需要的一切。 combination_with_replacement将生成给定长度的组合,其中包含来自给定iterable的重复元素。请注意,返回的值将是迭代器。

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

#4


1  

A pure python implementation :

纯python实现:

k=2  # k-uples
xmin=2
xmax=5 
n=xmax-xmin

l1 = [x for x in range(n**k)]
l2 = [[ x//n**(k-j-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 is :

l3是:

[[2 2]
 [2 3]
 [2 4]
 [3 2]
 [3 3]
 [3 4]
 [4 2]
 [4 3]
 [4 4]]

#5


-1  

What you are looking for is the cartesian product of the ranges. Luckily this already exists in itertools

您正在寻找的是范围的笛卡尔积。幸运的是,这已经存在于itertools中

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

#1


4  

You can use itertools.product which is just a convenience function for nested iterations. It also has a repeat-argument if you want to repeat the same iterable multiple times:

您可以使用itertools.product,它只是嵌套迭代的便利函数。如果你想多次重复相同的迭代,它也有一个repeat参数:

>>> 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 the list of list you could use map:

要获取列表列表,您可以使用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's really efficient if you just iterate over it instead of casting it to a list. At least if that's possible in your program. For example:

但是,产品是一个迭代器,所以如果你只是迭代它而不是将它转换为列表,它真的很有效。至少如果你的程序可以做到这一点。例如:

>>> 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)

#2


6  

You can use itertools.product:

您可以使用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.

删除列表,返回生成器以提高内存效率。

#3


1  

itertools has everything you need. combinations_with_replacement will generate combinations of given length with repeating elements from given iterable. Note that returned value will be iterator.

itertools拥有您需要的一切。 combination_with_replacement将生成给定长度的组合,其中包含来自给定iterable的重复元素。请注意,返回的值将是迭代器。

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

#4


1  

A pure python implementation :

纯python实现:

k=2  # k-uples
xmin=2
xmax=5 
n=xmax-xmin

l1 = [x for x in range(n**k)]
l2 = [[ x//n**(k-j-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 is :

l3是:

[[2 2]
 [2 3]
 [2 4]
 [3 2]
 [3 3]
 [3 4]
 [4 2]
 [4 3]
 [4 4]]

#5


-1  

What you are looking for is the cartesian product of the ranges. Luckily this already exists in itertools

您正在寻找的是范围的笛卡尔积。幸运的是,这已经存在于itertools中

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