【问题标题】:Python: Generating all n-length arrays combinations of values within a rangePython:生成范围内值的所有 n 长度数组组合
【发布时间】:2017-07-10 22:19:08
【问题描述】:

好的。我正在寻找最聪明、更紧凑的方法来执行此功能

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

它应该为值 a、b、c 生成所有组合,如下所示:

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

等等……

但我希望它是灵活的,所以我可以更改范围或可迭代,以及生成的数组的长度。范围很容易:

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

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

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

很抱歉发了这么长的帖子。

【问题讨论】:

  • itertools 模块有一个 product 函数,可以完全满足您的需求。 from itertools import product; product(range(6), range(6), range(6))。无论迭代器放在最后一个循环中最快。

标签: python arrays python-3.x list-comprehension


【解决方案1】:

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

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

要获得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]]

然而product 是一个迭代器,所以如果你只是迭代它而不是将其转换为list,它会非常有效。至少如果这在你的程序中是可能的。例如:

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

【讨论】:

  • 我终于用[list(elem) for elem in product(*repeat(iterable, times))]做了一个单行本
【解决方案2】:

你可以使用itertools.product:

from itertools import product

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

删除list,返回一个生成器以提高内存效率。

【讨论】:

    【解决方案3】:

    itertools 有你需要的一切。 combinations_with_replacement 将生成给定长度与来自给定迭代的重复元素的组合。请注意,返回值将是迭代器。

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

    【讨论】:

    • 适用于其他情况,但我需要 [0,0,1] != [1,0,0]。顺序确实很重要。也许我应该解释得更好。不过我会写下来
    • 对,然后正如其他一些答案所述 - itertools.product 会更好。
    【解决方案4】:

    纯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 是:

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

    【讨论】:

    • 您应该查看代码。 *// 给出语法错误
    • 人们宁愿称其为“纯内置”实现。我发现它不是 Python 的,因为它不可读,并且可能比使用 Python 标准库中的功能更多的内存和时间开销。
    【解决方案5】:

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

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

    【讨论】:

      猜你喜欢
      • 2013-01-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-02-02
      • 2017-03-23
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多