简体   繁体   English

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

[英]Python: Generating all n-length arrays combinations of values within a range

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. 对不起这么长的帖子。

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. 删除list ,返回生成器以提高内存效率。

You can use itertools.product which is just a convenience function for nested iterations. 您可以使用itertools.product ,它只是嵌套迭代的便利函数。 It also has a repeat -argument if you want to repeat the same iterable multiple times: 如果你想多次重复相同的iterable它也有一个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 : 要获取listlist ,你可以使用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 . 但是product是一个迭代器,所以如果你只是迭代它而不是将它强制转换为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)

itertools has everything you need. itertools拥有您需要的一切。 combinations_with_replacement will generate combinations of given length with repeating elements from given iterable. combination_with_replacement将生成给定长度的组合,其中包含来自给定iterable的重复元素。 Note that returned value will be iterator. 请注意,返回的值将是迭代器。

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

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

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM