3 回答
TA贡献1858条经验 获得超8个赞
首先编写生成所有约束的生成器表达式(不是列表推导)。
from itertools import product
constraints = ((r, c, notIn(matrix[r-1],
getColumn(matrix, c),
getSubgrid(matrix, r, c)))
for r, c in product(range(1, len(matrix) + 1), repeat=2)
if matrix[r-1][c-1] == 0)
接下来,按条件筛选候选列表应只有一个元素。
ready_to_fill = filter(lambda c: len(c[2]) == 1, constraints)
现在,您可以完整地迭代ready_to_fill
for row, column, [value] in ready_to_fill:
matrix[row-1][column-1] = value
或者只是得到第一个(请记住,你可能还没有找到一个准备好填充的正方形):
try:
next_to_fill = next(ready_to_fill)
except StopIteration:
...
在 Python 3.8 中,您可以使用赋值表达式来检查是否存在这样的约束,并使用以下命令获取对它的引用:any
# No need for filter in this case
# If any returns True, next_to_fill will be the first constraint
# with a singleton list.
if any(len((next_to_fill := c)[2]) == 1 for c in constraints):
...
更新:要使所有内容达到并包括单例列表约束,生成器表达式不太方便。不过,您可以使用生成器函数。
def get_constraints():
for r, c in product(range(1, len(matrix) + 1), repeat=2):
if matrix[r-1][c-1]:
continue
v = notIn(matrix[r-1],
getColumn(matrix, c),
getSubgrid(matrix, r, c))
yield (r, c, v)
if len(v) == 1:
return
for row, column, [value] in get_constraints():
...
TA贡献1835条经验 获得超7个赞
假设您有一个函数,它只返回列表理解:
def getConstraints(matrix):
return [(row, column, notIn(matrix[row - 1], getColumn(matrix, column),
getSubgrid(matrix, row, column)))
for row in range(1, len(matrix) + 1)
for column in range(1, len(matrix) + 1)
if matrix[row - 1][column - 1] == 0]
我们可以很容易地将其重写为一个生成器,而不会破坏我们最初使用它的方式:yield
def getConstraints(matrix):
# probably can just use generator directly in most of your cases...
# but might as well keep this around for max compatibility.
return list(getConstraintsGENERATOR(matrix))
def getConstraintsGENERATOR(matrix):
for row in range(1, len(matrix) + 1):
for column in range(1, len(matrix) + 1):
if matrix[row - 1][column - 1] == 0:
x = notIn(matrix[row - 1],
getColumn(matrix, column),
getSubgrid(matrix, row, column)
)
yield (row, column, x)
现在,因为我们有一个正在处理值的函数,所以在早期添加一个案例变得微不足道,在你的情况下,我认为它会是,并且由于你想包含该元素,你会在.yieldreturnif len(x) == 1: returnyield
添加回答
举报