2013-09-24 43 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