我有一个问题。我正在编写一个数独求解器,例如对于正方形A1我想找到子网格中的9个相邻正方形的列表(A1,A2,A3,B1,B2,B3,C1,C2,C3)
我的计划是在A和1中拆分A1,然后返回'ABC'和'123'的叉积,但如果square [0] ='A,我无法弄清楚如何优雅地返回'ABC' ”。
我想找到一种优雅的方法来从一组列表中返回找到该元素的列表。 ['ABC','DEF','GHI'],当我输入A时,我想得到字符串'ABC'。
完整代码atm:
def cross_product(A, B):
"""Returns a list of the cross product of A and B."""
return [a+b for a in A for b in B]
rows = 'ABCDEFGHI'
cols = '123456789'
squares = cross_product(rows, cols) # List of 81 squares
def find_row(square):
"""
Returns list of strings with corresponding row values.
Example: find_row('A2') -> ['A1','A2', ..., 'A9']
"""
return cross_product(square[0], cols)
def find_col(square):
"""
Returns list of strings with corresponding col values.
Example: find_col('A2') -> ['A2','B2', ..., 'I2']
"""
return cross_product(rows, square[1])
def find_peers(square):
"""
Returns list of strings of shared squares in the unit.
Example: find_peers('A2') -> ['A1', 'A2', 'A3', 'B1' , ..., 'C3']
"""
for e in ['ABC','DEF','GHI']:
if square[0] in e:
r = e
for e in ['123','456','789']:
if square[1] in e:
c = e
return cross_product(r, c)
有没有办法让find_peers(square)更加pythonic?
答案 0 :(得分:2)
如果您正在对测试列表进行硬编码,则可以使用字典:
square_letter = {c: e for e in ['ABC','DEF','GHI'] for c in e}
square_number = {n: e for e in ['123','456','789'] for n in e}
r, c = square_letter[square[0]], square_number[square[1]]
square_letter
和square_number
词典只需要生成一次。使用字典然后给你一个O(1)(恒定时间)查找。
如果这对性能至关重要,您可以通过函数的默认参数将映射绑定为本地:
square_letter = {c: e for e in ['ABC','DEF','GHI'] for c in e}
square_number = {n: e for e in ['123','456','789'] for n in e}
def find_peers(square, _letter=square_letter, _number=square_number):
"""
Returns list of strings of shared squares in the unit.
Example: find_peers('A2') -> ['A1', 'A2', 'A3', 'B1' , ..., 'C3']
"""
return cross_product(_letter[square[0]], _number[square[1]])
演示:
>>> def cross_product(A, B):
... """Returns a list of the cross product of A and B."""
... return [a+b for a in A for b in B]
...
>>> square_letter = {c: e for e in ['ABC','DEF','GHI'] for c in e}
>>> square_number = {n: e for e in ['123','456','789'] for n in e}
>>> def find_peers(square, _letter=square_letter, _number=square_number):
... """
... Returns list of strings of shared squares in the unit.
... Example: find_peers('A2') -> ['A1', 'A2', 'A3', 'B1' , ..., 'C3']
... """
... return cross_product(_letter[square[0]], _number[square[1]])
...
>>> find_peers('A2')
['A1', 'A2', 'A3', 'B1', 'B2', 'B3', 'C1', 'C2', 'C3']
>>> find_peers('E8')
['D7', 'D8', 'D9', 'E7', 'E8', 'E9', 'F7', 'F8', 'F9']
答案 1 :(得分:2)
另一种解决方案,不使用dict:
from itertools import product
rows = list('ABCDEFGHI')
cols = list('123456789')
square_width = 3
def find_peers(cell):
row, column = cell
row_idx = rows.index(row)
column_idx = cols.index(column)
first_row = row_idx - row_idx % square_width
first_column = column_idx - column_idx % square_width
rows_range = rows[first_row:first_row + square_width]
columns_range = cols[first_column:first_column + square_width]
return [
row + column for row, column in product(rows_range, columns_range)
]
>>> find_peers('A1')
['A1', 'A2', 'A3', 'B1', 'B2', 'B3', 'C1', 'C2', 'C3']
>>> find_peers('D1')
['D1', 'D2', 'D3', 'E1', 'E2', 'E3', 'F1', 'F2', 'F3']
>>> find_peers('G1')
['G1', 'G2', 'G3', 'H1', 'H2', 'H3', 'I1', 'I2', 'I3']
>>> find_peers('G4')
['G4', 'G5', 'G6', 'H4', 'H5', 'H6', 'I4', 'I5', 'I6']