在条件下在任意嵌套列表中查找组合

时间:2017-01-01 13:23:16

标签: python list-comprehension nested-lists

我想在有限的点网格上找到可能的路径。比如说,起点是(x,y)。然后路径中的下一个点(m,n)由条件

给出
  1. (m!= x)和(n!= y)即。我排除了以前的行和列。
  2. n<是的。我总是跳下去。
  3. m,n> = 0即。所有点始终在第一象限
  4. 停止标准是指一个点位于x轴上。
  5. 因此,生成这些'路径的所有可能组合。可能的。

    以下是我的尝试。

    def lisy(x,y):
        return [(i,j) for i in range(4,0,-1) for j in range(4,0,-1) if(i!=x and j<y)]
    
    def recurse(x,y):
        if (not lisy(x,y)):
            return (x,y)
        else:
            return [(x,y), [recurse(i,j) for i,j in lisy(x,y)]]
    

    输出:

    In [89]: recurse(1,4)
    Out[89]: 
    [(1, 4),
     [[(4, 3),
       [[(3, 2), [(4, 1), (2, 1), (1, 1)]],
        (3, 1),
        [(2, 2), [(4, 1), (3, 1), (1, 1)]],
        (2, 1),
        [(1, 2), [(4, 1), (3, 1), (2, 1)]],
        (1, 1)]],
      [(4, 2), [(3, 1), (2, 1), (1, 1)]],
      (4, 1),
      [(3, 3),
       [[(4, 2), [(3, 1), (2, 1), (1, 1)]],
        (4, 1),
        [(2, 2), [(4, 1), (3, 1), (1, 1)]],
        (2, 1),
        [(1, 2), [(4, 1), (3, 1), (2, 1)]],
        (1, 1)]],
      [(3, 2), [(4, 1), (2, 1), (1, 1)]],
      (3, 1),
      [(2, 3),
       [[(4, 2), [(3, 1), (2, 1), (1, 1)]],
        (4, 1),
        [(3, 2), [(4, 1), (2, 1), (1, 1)]],
        (3, 1),
        [(1, 2), [(4, 1), (3, 1), (2, 1)]],
        (1, 1)]],
      [(2, 2), [(4, 1), (3, 1), (1, 1)]],
      (2, 1)]]
    

    这给了我一个从每个点可能的新点的嵌套列表。

    有谁能告诉我如何处理从recurse(1,4)获得的列表?

    edit1:

    有效地,我从一个给定的起始点跳跃(在一个4x4网格[有限]中),满足上述三个条件,直到满足停止标准,即。 m,n > 0

1 个答案:

答案 0 :(得分:1)

我在我的生成器gridpaths()的docstring中阐明了我正在使用的要求。请注意,我将网格的水平大小作为全局变量,并且网格的垂直大小无关紧要,路径点的x坐标可以达到但不超过该全局值,并且x坐标为非连续的路径点可以相等(尽管连续的路径点必须具有不同的x坐标)。我改变了例程的名称,但保留了你拥有的参数。这个版本的代码增加了路径上最后一个点的y坐标必须为1的要求,并且接受参数也更安全。

这是一个列表生成器,所以我的测试代码显示了生成器的大小,然后打印所有列表。

def gridpaths(x, y):
    """Generate all paths starting at (x,y) [x and y must be positive
    integers] where, if (m,n) is the next point in the path after
    (x,y), then m and n are positive integers, m <= xsize [xsize is a
    global variable], m != x, and n < y, and so on for all consecutive
    path points. The final point in the path must have a y-coordinate
    of 1. Paths are yielded in lexicographic order."""
    def allgridpaths(x, y, pathsofar):
        """Generate all such paths continuing from pathssofar without
        the y == 1 requirement for the final path point."""
        newpath = pathsofar + [(x, y)]
        yield newpath
        for m in range(1, xsize+1):
            if m != x:
                for n in range(1, y):
                    for path in allgridpaths(m, n, newpath):
                        yield path
    x, y = max(int(x), 1), max(int(y), 1)  # force positive integers
    for path in allgridpaths(x, y, []):
        # Only yield paths that end at y == 1
        if path[-1][1] == 1:
            yield path

# global variable: horizontal size of grid
xsize = 4

print(sum(1 for p in gridpaths(1, 4)), 'paths total.')
for p in gridpaths(1, 4):
    print(p)

打印输出显示4x4网格中的点(1,4)产生48条路径。事实上,gridpaths(x, y)将返回(xsize - 1) * xsize ** (y - 2)个路径,这些路径可以非常快速地增长。这就是我编写列表生成器而不是列表列表的原因。如果您的要求与我的要求不同,请告诉我。上述代码的打印输出为:

48 paths total.
[(1, 4), (2, 1)]
[(1, 4), (2, 2), (1, 1)]
[(1, 4), (2, 2), (3, 1)]
[(1, 4), (2, 2), (4, 1)]
[(1, 4), (2, 3), (1, 1)]
[(1, 4), (2, 3), (1, 2), (2, 1)]
[(1, 4), (2, 3), (1, 2), (3, 1)]
[(1, 4), (2, 3), (1, 2), (4, 1)]
[(1, 4), (2, 3), (3, 1)]
[(1, 4), (2, 3), (3, 2), (1, 1)]
[(1, 4), (2, 3), (3, 2), (2, 1)]
[(1, 4), (2, 3), (3, 2), (4, 1)]
[(1, 4), (2, 3), (4, 1)]
[(1, 4), (2, 3), (4, 2), (1, 1)]
[(1, 4), (2, 3), (4, 2), (2, 1)]
[(1, 4), (2, 3), (4, 2), (3, 1)]
[(1, 4), (3, 1)]
[(1, 4), (3, 2), (1, 1)]
[(1, 4), (3, 2), (2, 1)]
[(1, 4), (3, 2), (4, 1)]
[(1, 4), (3, 3), (1, 1)]
[(1, 4), (3, 3), (1, 2), (2, 1)]
[(1, 4), (3, 3), (1, 2), (3, 1)]
[(1, 4), (3, 3), (1, 2), (4, 1)]
[(1, 4), (3, 3), (2, 1)]
[(1, 4), (3, 3), (2, 2), (1, 1)]
[(1, 4), (3, 3), (2, 2), (3, 1)]
[(1, 4), (3, 3), (2, 2), (4, 1)]
[(1, 4), (3, 3), (4, 1)]
[(1, 4), (3, 3), (4, 2), (1, 1)]
[(1, 4), (3, 3), (4, 2), (2, 1)]
[(1, 4), (3, 3), (4, 2), (3, 1)]
[(1, 4), (4, 1)]
[(1, 4), (4, 2), (1, 1)]
[(1, 4), (4, 2), (2, 1)]
[(1, 4), (4, 2), (3, 1)]
[(1, 4), (4, 3), (1, 1)]
[(1, 4), (4, 3), (1, 2), (2, 1)]
[(1, 4), (4, 3), (1, 2), (3, 1)]
[(1, 4), (4, 3), (1, 2), (4, 1)]
[(1, 4), (4, 3), (2, 1)]
[(1, 4), (4, 3), (2, 2), (1, 1)]
[(1, 4), (4, 3), (2, 2), (3, 1)]
[(1, 4), (4, 3), (2, 2), (4, 1)]
[(1, 4), (4, 3), (3, 1)]
[(1, 4), (4, 3), (3, 2), (1, 1)]
[(1, 4), (4, 3), (3, 2), (2, 1)]
[(1, 4), (4, 3), (3, 2), (4, 1)]