NumPy的ndarray
类中有一个跨度(strides)属性域,实现为一个元组。在遍历数组时,用跨度来指明每一个维度上的步进值是多少字节。我们将巧妙运用跨度技巧,把数独谜题划分为3×3的九宫格形式。
对数独游戏规则的解释超出了本章的范围,请访问 http://en.wikipedia.org/wiki/Sudoku 获取更多相关信息。
具体步骤
- 定义数独谜题数组。
首先定义数独谜题数组,其内容就是一个真实的、已经解开的数独谜题。
sudoku = numpy.array([
[2, 8, 7, 1, 6, 5, 9, 4, 3],
[9, 5, 4, 7, 3, 2, 1, 6, 8],
[6, 1, 3, 8, 4, 9, 7, 5, 2],
[8, 7, 9, 6, 5, 1, 2, 3, 4],
[4, 2, 1, 3, 9, 8, 6, 7, 5],
[3, 6, 5, 4, 2, 7, 8, 9, 1],
[1, 9, 8, 5, 7, 3, 4, 2, 6],
[5, 4, 2, 9, 1, 6, 3, 8, 7],
[7, 3, 6, 2, 8, 4, 5, 1, 9]
])
- 计算跨度。
ndarray
类的itemsize
域指明数组中每个元素所占用的字节数。利用itemsize
来计算跨度:
strides = sudoku.itemsize *
numpy.array([27, 3, 9, 1])
- 划分九宫格。
用numpy.lib.stride_tricks模块中的as_strided
函数,把谜题数组划分为九宫格的形式:
squares = numpy.lib.stride_tricks.as_strided
(sudoku, shape=shape, strides=strides)
print(squares)
这样就能把各个宫格分别打印出来。
[[[[2 8 7]
[9 5 4]
[6 1 3]]
[[1 6 5]
[7 3 2]
[8 4 9]]
[[9 4 3]
[1 6 8]
[7 5 2]]]
[[[8 7 9]
[4 2 1]
[3 6 5]]
[[6 5 1]
[3 9 8]
[4 2 7]]
[[2 3 4]
[6 7 5]
[8 9 1]]]
[[[1 9 8]
[5 4 2]
[7 3 6]]
[[5 7 3]
[9 1 6]
[2 8 4]]
[[4 2 6]
[3 8 7]
[5 1 9]]]]
本攻略的完整代码如下:
import numpy
sudoku = numpy.array([
[2, 8, 7, 1, 6, 5, 9, 4, 3],
[9, 5, 4, 7, 3, 2, 1, 6, 8],
[6, 1, 3, 8, 4, 9, 7, 5, 2],
[8, 7, 9, 6, 5, 1, 2, 3, 4],
[4, 2, 1, 3, 9, 8, 6, 7, 5],
[3, 6, 5, 4, 2, 7, 8, 9, 1],
[1, 9, 8, 5, 7, 3, 4, 2, 6],
[5, 4, 2, 9, 1, 6, 3, 8, 7],
[7, 3, 6, 2, 8, 4, 5, 1, 9]
])
shape = (3, 3, 3, 3)
strides = sudoku.itemsize * numpy.array([27, 3, 9, 1])
squares = numpy.lib.stride_tricks.as_strided
(sudoku, shape=shape, strides=strides)
print(squares)
攻略小结
我们应用跨度技巧,把数独谜题划分为3×3的九宫格形式。跨度告诉我们,在遍历数独数组时,每一步需要跳过多少字节。