2013-12-22 23 views
4

讓我試試這個代碼的列表理解使用返回意外的結果

(for [x (range 1 8) y (range 1 8) :while (and (< x y) (even? x))] [x y]) 

,並取回()

但我試試這個:

(for [x (range 1 8) y (range 1 8) :while (and (< y x) (even? x))] [x y]) 

,我得到了想要的結果。 改變x和y的位置有什麼影響?第一個代碼段不應該返回一個空列表..畢竟有必須有的甚至X的除y

+0

':while'沒有綁定到整個'for'構造,只有迭代到'y'的部分,然後*在每次增加'x'時重新啓動*。查看我的答案瞭解更多詳情。 – dg123

+0

另請參閱http://clojuredocs.org/clojure_core/clojure.core/for,並查看演示':when'和':while'之間區別的部分。 – dg123

回答

8

在Clojure中較小的,(for [x (range 1 8) y (range 1 8)] [x y])x1運行笛卡爾乘積yy回到7爲每每次迭代x

從REPL:

user=> (for [x (range 1 8) y (range 1 8)] [x y]) 
([1 1] [1 2] [1 3] [1 4] [1 5] [1 6] [1 7] [2 1] [2 2] [2 3] [2 4] [2 5] [2 6] [2 7] [3 1] [3 2] [3 3] [3 4] [3 5] [3 6] [3 7] [4 1] [4 2] [4 3] [4 4] [4 5] [4 6] [4 7] [5 1] [5 2] [5 3] [5 4] [5 5] [5 6] [5 7] [6 1] [6 2] [6 3] [6 4] [6 5] [6 6] [6 7] [7 1] [7 2] [7 3] [7 4] [7 5] [7 6] [7 7]) 

在你的例子,:whiley而不是x有關。因此:while適用於y的每次迭代,然後在x的下一次迭代之後重新啓動

爲了使這更清楚,請注意,你也可以用:while關聯x

user=> (for [x (range 1 8) :while (odd? x) y (range 1 8)] [x y]) 
([1 1] [1 2] [1 3] [1 4] [1 5] [1 6] [1 7]) 

它運行循環x是奇數,則休息。

所以在你的第一個例子,:while休息每一次迭代上yy等於1因爲沒有x值,對於這個(and (< x 1) (even? x))持有true

你的第二個例子,在另一方面,適用於中y因爲(< 1 1)產量false第一次迭代,因爲即使:while短時休息,y第二次迭代成功,因爲x開始從2,所以如果y1,並且(and (< y x) (even? x))(and (< 1 2) (even? 2)),其評估爲true

請參閱http://clojuredocs.org/clojure_core/clojure.core/for瞭解更多詳情。特別是顯示:when:while之間區別的部分。