2015-09-06 21 views
0

我有一個問題。我正在編寫一個數獨求解器,例如,對於A1的平方,我想查找子網格中的9個相鄰方塊的列表(A1,A2,A3,B1,B2,B3,C1,C2,C3)如果在該元素中找到某個字符,返回列表元素的Python方法

我的計劃是在A和1中分割A1,然後返回'ABC'和'123'的叉積,但如果square [0] ='A',我無法弄清楚如何優雅地返回'ABC'。

我想找到一個優雅的方式來返回從一組列表中找到元素的列表。 ['ABC','DEF','GHI'],當我輸入A時,我想得到字符串'ABC'。

的完整代碼大氣壓:

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(方形)更Python?

回答

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_lettersquare_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'] 
+0

謝謝。這肯定看起來Pythonic。 (Bedankt,Martijn!) – Rainymood

2

另一種解決方案,而無需使用字典:

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'] 
相關問題