切片多维列表的问题

时间:2014-05-28 04:30:22

标签: python

我知道如何切割常规列表,但使用多列表让我疯狂。 我有一个9x9的方块,我试图在每个3x3的方格上运行检查。

x x x | x x x | x x x
x x x | x x x | x x x 
x x x | x x x | x x x
---------------------
x x x | x x x | x x x
x x x | x x x | x x x 
x x x | x x x | x x x
---------------------
x x x | x x x | x x x
x x x | x x x | x x x 
x x x | x x x | x x x

我不得不蛮力。我知道有一种更简单,更好的方式,而不必拥有

square_1 = board[0][:3] + board[1][:3] + board[2][:3]
square_2 = board[0][3:6] + board[1][3:6] + board[2][3:6]
square_3 = board[0][6:9] + board[1][6:9] + board[2][6:9]

4 个答案:

答案 0 :(得分:1)

board = [[10*r + c for c in range(1,10)] for r in range(1,10)]
squares = [[board[3*r + i][3*c + j] for i,j in itertools.product(range(3), repeat=2)] for r,c in itertools.product(range(3), repeat=2)]

输出:

In [18]: board = [[10*r + c for c in range(1,10)] for r in range(1,10)]

In [19]: board
Out[19]: 
[[11, 12, 13, 14, 15, 16, 17, 18, 19],
 [21, 22, 23, 24, 25, 26, 27, 28, 29],
 [31, 32, 33, 34, 35, 36, 37, 38, 39],
 [41, 42, 43, 44, 45, 46, 47, 48, 49],
 [51, 52, 53, 54, 55, 56, 57, 58, 59],
 [61, 62, 63, 64, 65, 66, 67, 68, 69],
 [71, 72, 73, 74, 75, 76, 77, 78, 79],
 [81, 82, 83, 84, 85, 86, 87, 88, 89],
 [91, 92, 93, 94, 95, 96, 97, 98, 99]]

In [20]: squares = [[board[3*r + i][3*c + j] for i,j in itertools.product(range(3), repeat=2)] for r,c in itertools.product(range(3), repeat=2)]

In [21]: squares
Out[21]: 
[[11, 12, 13, 21, 22, 23, 31, 32, 33],
 [14, 15, 16, 24, 25, 26, 34, 35, 36],
 [17, 18, 19, 27, 28, 29, 37, 38, 39],
 [41, 42, 43, 51, 52, 53, 61, 62, 63],
 [44, 45, 46, 54, 55, 56, 64, 65, 66],
 [47, 48, 49, 57, 58, 59, 67, 68, 69],
 [71, 72, 73, 81, 82, 83, 91, 92, 93],
 [74, 75, 76, 84, 85, 86, 94, 95, 96],
 [77, 78, 79, 87, 88, 89, 97, 98, 99]]

现在,如果您希望方块也是二维的,那么您可以这样做:

squares = [[[board[3*r + i][3*c + j] for j in range(3)] for i in range(3)] for r,c in itertools.product(range(3), repeat=2)]

输出:

Out[22]: 
[[[11, 12, 13], [21, 22, 23], [31, 32, 33]],
 [[14, 15, 16], [24, 25, 26], [34, 35, 36]],
 [[17, 18, 19], [27, 28, 29], [37, 38, 39]],
 [[41, 42, 43], [51, 52, 53], [61, 62, 63]],
 [[44, 45, 46], [54, 55, 56], [64, 65, 66]],
 [[47, 48, 49], [57, 58, 59], [67, 68, 69]],
 [[71, 72, 73], [81, 82, 83], [91, 92, 93]],
 [[74, 75, 76], [84, 85, 86], [94, 95, 96]],
 [[77, 78, 79], [87, 88, 89], [97, 98, 99]]]

因此,squares[0]是以下二维列表:

[[11, 12, 13], 
 [21, 22, 23], 
 [31, 32, 33]]

答案 1 :(得分:0)

你可以从这样的事情开始:

square_1 = [board[i][j] for i in range(0,3) for j in range(0,3)]
square_2 = [board[i][j] for i in range(0,3) for j in range(2,6)]
...

或者稍微优雅一点:

def square(a,b):
    square[a][b] = [board[i][j] for i in range(3*a-3,3*a) for j in range(3*b-3, 3*b)]

答案 2 :(得分:0)

重新设计数据结构可能有助于仅使用包含81个元素的单个列表。 x,y处的值将存储在一维列表中的索引x+9y处。你的方块将是:

squares = [[board[x+3*i+9*y+27*j] for y, x in itertools.product(range(3), repeat=2)]
           for j, i in itertools.product(range(3), repeat=2)]

这种表示方法非常方便,因为您可以通过几个简单的计算轻松计算索引所属的行,列和方(我猜你正在解决数独,所以你需要这些) :

row = index // 9
column = index % 9
square = index // 3 % 3 + index // 27 * 3

答案 3 :(得分:-1)

从根本上说,如果没有NumPy之类的东西,就无法优化列表索引的语法。但是,您可以使用子例程。

def sumrows(bd, n):
    return bd[0][n:n+3] + bd[1][n:n+3] + bd[2][n:n+3]

square_1 = sumrows(board, 0)
square_2 = sumrows(board, 3)
square_3 = sumrows(board, 6)

NumPy版本更强大。

def sumrows(bd, x, y):
    return bd[x:x+3,y:y+3]

square_1_1 = sumrows(board, 0, 0)
square_1_2 = sumrows(board, 0, 3)
square_1_3 = sumrows(board, 0, 6)

square_2_1 = sumrows(3, 0)
square_2_2 = sumrows(3, 3)
square_2_3 = sumrows(3, 6)
# ...