6

我有一个可迭代的涵盖了一个巨大的搜索空间。我的计划是不让脚本终止,而是在一段时间后杀死脚本。迭代itertools.product以不同的顺序没有创建列表

现在我需要这个空间的笛卡尔积,并在那里搜索。 itertools.product产生顺序如下:

>>> list(itertools.product(range(3), repeat=2)) 
[(0, 0), (0, 1), (0, 2), (1, 0), (1, 1), (1, 2), (2, 0), (2, 1), (2, 2)] 

当我想以一种类似于对角线为了寻找:

[(0, 0), (0, 1), (1, 0), (0, 2), (1, 1), (2, 0), (1, 2), (2, 1), (2, 2)] 

sorted与一些关键的函数,返回数组的元素的总和将是我的规则方法,但是需要检查所有需要检查的数据,这在我的情况下是不可行的。有没有办法做到这一点?

此问题与this one非常相似,但仍有sorted仍在使用中。另外我不会很快看到如何将ordered_combinations改编为ordered_product

+0

输出顺序应该如何寻找'范围(4),重复= 3'? –

+0

问题陈述限于'repeat = 2',因为OP根据矩阵M的对角线思考,行数和列数为N(在这种情况下为3)。偶然事件'itertools.product'会产生矩阵中所有元素位置的列表,而OP会试图操纵那些预期的输出,但真正应该做的是基于类矩阵问题陈述的完全不同的解决方案。 –

+0

@Chris_Rands我猜仍然按照元素的总和顺序排列,按字典顺序排列等于一个元素。尽管我只对repeat = 2的情况感兴趣,但我并不关心对角线的方向,例如,我不在乎是(0,1)还是(1,0) 。 @ŁukaszRogalski好,我就是这么想的,是的,它不一定是答案的结构(尽管它可能是)。 – qpllb

回答

0

它实际上很容易计算的对角线指数为repeat=2情况:

def diagonal_product(inp): 
    inp = tuple(inp) 
    n = len(inp) 
    # upper left triangle 
    for i in range(n): 
     for j in range(i+1): 
      yield inp[i-j], inp[j] 
    # lower right triangle 
    for i in range(1, n): 
     for j in range(n-i): 
      yield inp[n-j-1], inp[i+j] 

只是为了显示结果:

>>> list(diagonal_product(range(4))) 
[(0, 0), (1, 0), (0, 1), (2, 0), (1, 1), (0, 2), (3, 0), (2, 1), (1, 2), 
(0, 3), (3, 1), (2, 2), (1, 3), (3, 2), (2, 3), (3, 3)] 

>>> list(diagonal_product(range(3))) 
[(0, 0), (1, 0), (0, 1), (2, 0), (1, 1), (0, 2), (2, 1), (1, 2), (2, 2)] 

函数本身可能会更复杂一些(或更慢)比它需要,但我还没有找到任何参考实现这种情况下。

range输入你也可以避免所有的索引和的情况下,只返回指数:

def diagonal_product(n): 
    # upper left triangle 
    for i in range(n): 
     for j in range(i+1): 
      yield i-j, j 
    # lower right triangle 
    for i in range(1, n): 
     for j in range(n-i): 
      yield n-j-1, i+j 

list(diagonal_product(3)) 
# [(0, 0), (1, 0), (0, 1), (2, 0), (1, 1), (0, 2), (2, 1), (1, 2), (2, 2)]