2013-09-24 44 views
2

這是一個遞歸解決方案,來自https://wiki.python.org/moin/SimplePrograms的8個皇后問題。我很難理解如何/爲什麼解決函數中的return語句有效。乍一看,它看起來像違反了規則(比如,解決方案在return語句中的循環之前沒有被聲明或賦值,但它出現在return語句的循環之前),但是我可以成功運行它,所以我好奇,想了解它是如何工作以及爲什麼有些人可能選擇了這種方式寫(是混亂?短?因爲其他限制我還不明白嗎?)這個return語句到底指示程序做什麼?

BOARD_SIZE = 8 

def under_attack(col, queens): 
    left = right = col 

    for r, c in reversed(queens): 
     left, right = left - 1, right + 1 

     if c in (left, col, right): 
      return True 
    return False 

def solve(n): 
    if n == 0: 
     return [[]] 

    smaller_solutions = solve(n - 1) 

    return [solution+[(n,i+1)] 
     for i in xrange(BOARD_SIZE) 
      for solution in smaller_solutions 
       if not under_attack(i+1, solution)] 
for answer in solve(BOARD_SIZE): 
    print answer 

我熟悉問題的遞歸解決方案從一些實驗和我已經學過的課程,但我作爲一個整體對Python來說很新(我主要在類和我自己中使用過java和C)。

有沒有人有一個很好的方式來解釋這個語法是如何工作的,或者我可以學習的其他例子可能會幫助我理解它?這真的讓我很好奇...

+0

@DanielRoseman:這不是無效的語法。這是一個複雜的列表生成器內部 – justhalf

+1

'返回'只是一個列表理解拆分爲多行,可能爲「可讀性」。 – Volatility

+0

@justhalf是的,只是注意到了。 –

回答

3

你在問列表解析。它是Python的方法來完成功能映射(對列表中的每個元素應用函數)和過濾器(在特定條件下過濾列表)。

解釋這個最簡單的方法是一些例子。

說:

>>> l = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] 
>>> [2 * i for i in l] 
[2, 4, 6, 8, 10, 12, 14, 16, 18, 20] 
>>> [i for i in l if i > 5] 
[6, 7, 8, 9, 10] 

現在這些可以組合,並且可以使用任意數量的對的:

>>> # squares of even numbers below 10 
>>> [i * i for i in range(10) if i%2 == 0] 
[0, 4, 16, 36, 64] 
>>> # concatenating all lists 
>>> ll = [[1, 2], [3, 4], [5, 6], [7, 8], [8, 10]] 
>>> [i for l in ll for i in l] 
[1, 2, 3, 4, 5, 6, 7, 8, 8, 10] 
5

我猜你的困惑是這行代碼:

 v---- this starts the list 
return [solution+[(n,i+1)] 
     for i in xrange(BOARD_SIZE) 
      for solution in smaller_solutions 
       if not under_attack(i+1, solution)] 
                ^-- this ends the list 

這實際上是一個list comprehension,它是創建列表的簡短方式。

這是該循環的longhand版本。

x = [] 
for i in xrange(BOARD_SIZE): 
    for solution in smaller_solutions: 
     if not under_attack(i+1, solution): 
      x.append(solution+[(n, i+1)]) 
return x 
+0

這種情況下的longhand版本更具可讀性。 –

+0

@DanielRoseman:一旦習慣了它,可讀性差別不大。理解速度更快。 – Noctua

+0

啊哈!速記說得很清楚,非常感謝。 – Malafat