从Common Lisp中的嵌套循环返回

Mir*_*lov 3 loops common-lisp nested-loops

我正在尝试将此Python代码转换为Common Lisp:

for a in xrange(1,1000):
    for b in xrange(a,1000):
        c = (a**2 + b**2) ** 0.5
        s = a + b + c
        if s == 1000:
            return a * b * c
Run Code Online (Sandbox Code Playgroud)

我的第一次尝试是:

(loop for a from 1 to 999
      do (loop for b from a to 999
               for c = (sqrt (+ (expt a 2) (expt b 2)))
               for s = (+ a b c)
               until (= s 1000)
               finally return (* a b c))))
Run Code Online (Sandbox Code Playgroud)

这不起作用.我的任务是:当s命中1000时,使整个表达式返回(* a b c).如何从嵌套循环宏中返回一些值?

The*_*Ent 11

您可以使用blockreturn-from运算符:block建立命名的代码块,您可以return-from使用块的名称从此块返回

(let (c s)
  (block nested-loops
    (do ((a 1 (1+ a))) ((= a 999))
      (do ((b a (1+ b))) ((= b 999))
        (setf c (sqrt (+ (expt a 2) (expt b 2)))
              s (+ a b c))
        (if (= s 1000)
            (return-from nested-loops (* a b c)))))))
Run Code Online (Sandbox Code Playgroud)

PS,我不在loop这里使用,我只是习惯了do.

也来自http://www.gigamonkeys.com/book/loop-for-black-belts.html

要允许RETURN-FROM用于从特定循环返回(在嵌套LOOP表达式时很有用),可以使用名为的循环关键字命名LOOP.如果一个命名子句出现在循环中,它必须是第一个子句.对于一个简单的示例,假设列表是列表列表,并且您希望找到与这些嵌套列表之一中的某些条件匹配的项.你可以用一对嵌套循环找到它,如下所示:

(loop named outer for list in lists do
     (loop for item in list do
          (if (what-i-am-looking-for-p item)
            (return-from outer item))))
Run Code Online (Sandbox Code Playgroud)


Bar*_*mar 7

Python return语句不从循环返回,它从包含循环的整个函数返回.在Common Lisp中,函数建立一个与函数同名的隐式块.所以你可以使用:

(return-from function-name (* a b c))
Run Code Online (Sandbox Code Playgroud)

执行相当于Python代码的返回.