列出数独块的列表理解

List comprehension to list Sudoku blocks

我正在尝试在 数独 网格中定义方块。因此,例如一个 4x4 数独有 4 个 2x2 的块。

我现在拥有的是:

import itertools
import math

lines = [[1,0,3,4],[4,0,2,1],[2,1,4,3],[3,4,1,2]]
length = len(lines[0])
sqrt = int(math.sqrt(length))
blocks = [[lines[r+i][c+j] for i,j in itertools.product(range(0, length, sqrt), repeat = 2)]
     for r,c in itertools.product(range(sqrt), repeat = 2)]

但我似乎无法正确理解列表,因为块的输出是:

[[1,3,2,4],[0,4,1,3],[4,2,3,1],[0,1,4,2]]

但应该是:

[[1,0,4,0],[3,4,2,1],[2,1,3,4],[4,3,1,2]]

有人可以帮我解决这个问题吗?

如果我没理解错的话,你要进行平铺,意思就是输入[[a,b,c,d],[e,f,g,h],[i,j,k,l],[m,n,o,p]]或者更方便的:

+--+--+
|ab|cd|
|ef|gh|
+--+--+
|ij|kl|
|mn|op|
+--+--+

转化为:[[a,b,e,f],[c,d,g,h],[i,j,m,n],[k,l,o,p]].

我认为你颠倒了嵌套列表的逻辑:

  • 外部列表应该考虑 block 标识符 bi,bj,因此:

    [... for bi,bj in itertools.product(range(0,length,sqrt), repeat = 2)]
    
  • 而内部列表理解应该遍历单元格:

    [lines[bi+i][bj+j] for i,j in itertools.product(range(sqrt), repeat = 2)]
    

结合这些得到:

[[lines[bi+i][bj+j] for i,j in itertools.product(range(sqrt), repeat = 2)] for bi,bj in itertools.product(range(0,length,sqrt), repeat = 2)]

或更方便阅读:

[
    [lines[bi+i][bj+j] for i,j in itertools.product(range(sqrt), repeat = 2)]
    for bi,bj in itertools.product(range(0,length,sqrt), repeat = 2)
]

使用 Pythons 交互 shell:

>>> [[lines[bi+i][bj+j] for i,j in itertools.product(range(sqrt), repeat = 2)] for bi,bj in itertools.product(range(0,length,sqrt), repeat = 2)]
[[1, 0, 4, 0], [3, 4, 2, 1], [2, 1, 3, 4], [4, 3, 1, 2]]

这看起来像预期的输出。