Functional programming 返回包含for循环执行结果的列表

Functional programming 返回包含for循环执行结果的列表,functional-programming,racket,Functional Programming,Racket,我刚刚开始学习球拍,我需要循环列表和索引 现在,我正在使用: 函数numeric和函数no numeric返回一个列表,我需要用这些函数返回的列表创建一个列表。但我不知道怎么做 也许和你在一起会更容易,但我不这么认为 如何使用for循环返回列表列表?首先,使用索引是遍历列表最糟糕的方法,应该避免:每个list ref操作都是打开的,因为要到达元素I,必须遍历它之前的所有I-1元素,使整个遍历成为一个巨大的^2操作。如果您确实需要它们,则生成一个单独的带有索引的列表 为了在列表中收集返回的数据,我

我刚刚开始学习球拍,我需要循环列表和索引

现在,我正在使用:

函数numeric和函数no numeric返回一个列表,我需要用这些函数返回的列表创建一个列表。但我不知道怎么做

也许和你在一起会更容易,但我不这么认为


如何使用for循环返回列表列表?

首先,使用索引是遍历列表最糟糕的方法,应该避免:每个list ref操作都是打开的,因为要到达元素I,必须遍历它之前的所有I-1元素,使整个遍历成为一个巨大的^2操作。如果您确实需要它们,则生成一个单独的带有索引的列表

为了在列表中收集返回的数据,我们可以利用来累积每次迭代的结果,甚至可以并行遍历多个元素序列。让我们把这些放在一起:

(for/list ([element list1]
           [index (in-range (length list1))])
  (if (number? element)
      (function-numeric list1 index list2)
      (function-no-numeric list1 index list3)))

我只是希望您不要在函数numeric和函数no numeric中再次使用list ref。也许有一种更好的方法来构造算法,避免索引——列表不应该以我们使用数组的方式使用!如果您的算法不能修改以避免索引,则考虑使用Atter,使用索引来优化快速项检索。初学者使用

,使用索引是遍历列表的最坏的可能方式,并且应该避免:每个列表REF操作都在进行,因为要到达元素i,您必须遍历它之前的所有i-1元素,从而使整个遍历操作在^2上运行。如果您确实需要它们,则生成一个单独的带有索引的列表

为了在列表中收集返回的数据,我们可以利用来累积每次迭代的结果,甚至可以并行遍历多个元素序列。让我们把这些放在一起:

(for/list ([element list1]
           [index (in-range (length list1))])
  (if (number? element)
      (function-numeric list1 index list2)
      (function-no-numeric list1 index list3)))

我只是希望您不要在函数numeric和函数no numeric中再次使用list ref。也许有一种更好的方法来构造算法,避免索引——列表不应该以我们使用数组的方式使用!如果你的算法不能被修改以避免索引,那么考虑使用A代替,这是使用索引快速检索的优化。

如果你刚开始学习球拍,我真的推荐反对和//LIST。你应该首先了解基本的问题:什么是列表

也称为链表的列表是:

空的或 一个元素与另一个列表的组合 比如说,

empty是一个空列表。 cons 9 empty是一个包含一个元素的列表:9。 cons 3 cons 9 empty是一个包含两个元素的列表:3和9。 给出一个列表,除了可以执行的cons之外,这里还有一些基本操作

空的lst:检查lst是否为空。例如,空的?empty计算为t但为空?cons 1的计算结果为f。 first lst:如果lst是cons,则返回lst的第一个元素。如果lst为空,则出错。例如,first cons 2 cons 1 empty计算为2,但first empty会导致错误。 rest lst:如果lst是cons,则返回lst的其余部分。如果lst为空,则出错。例如,rest cons 2 cons 1 empty计算为cons 1 empty,但第一个空会导致错误。 通过组合使用first和rest,您可以访问任何元素。如果列表cons 5 cons 4 cons 3 cons 2为空,并且您希望访问第二个元素,该元素应为4,您将计算:

剩余lst将为您提供cons 4 cons 3 cons 2空 第一个休息的lst将给你4。 list是一个简单的缩写,用于轻松构建列表

list是empty的缩写。 列表9是cons 9 empty的缩写 列表1 2 3是cons 1 cons 2 cons 3 empty的缩写。 其他列表操作仅使用上述基本操作实现。例如,list ref的实现如下所示:

(define (my-list-ref xs i)
  (cond
    ;; a list is either empty
    [(empty? xs) (error 'out-of-bound)]
    ;; or a cons, where it's safe to use first and rest
    [(= i 0) (first xs)]
    [else (my-list-ref (rest xs) (- i 1))]))

;; (my-list-ref (list) 0) => out-of-bound error
;; (my-list-ref (list 4 5 6) 0) => 4
;; (my-list-ref (list 4 5 6) 1) => 5
;; (my-list-ref (list 4 5 6) 2) => 6
正如奥斯卡·洛佩斯所提到的,虽然列表看起来类似于数组,但思考它们的方式却大不相同。使用list ref需要Oi,如果您想获得第i个元素一次,这很好,但这不是访问所有元素甚至很多元素的正确方法。相反,只需一次访问所有这些文件。例如,如果我有一个列表2 3 4,并且我想获得另一个列表,在原始列表的每个元素中添加10,我会写:

(define (add10-all xs)
  (cond
    ;; a list is either empty, where (add10-all empty) should return empty
    [(empty? xs) empty]
    ;; or a cons, where we want to to add 10 to the first element, 
    ;; recur on the rest, and create a resulting cons
    [else (cons (+ 10 (first xs)) (add10-all (rest xs)))]))

;; (add10-all (list)) => (list)
;; (add10-all (list 2 3 4)) => (list 12 13 14)
;; assume function-numeric consumes (1) an element from list1 (2) the corresponding element in list2 (3) an index
;; assume function-no-numeric consumes (1) an element from list1 (2) the corresponding element in list3 (3) an index

(define (foo list1 list2 list3 i)
  (cond
    [(empty? list1) empty]
    [else
     (define e (first list1))
     (define out (if (number? e)
                     (function-numeric e (first list2) i)
                     (function-no-numeric e (first list3) i)))
     (cons out (foo (rest list1) (rest list2) (rest list3) (+ i 1)))]))

(foo list1 list2 list3 0)
在您的情况下,您可能需要:

;; assume function-numeric consumes an element from list1 and the whole list2
;; assume function-no-numeric consumes an element from list1 and the whole list3

(define (foo list1 list2 list3)
  (cond
    [(empty? list1) empty]
    [else
     (define e (first list1))
     (define out (if (number? e)
                     (function-numeric e list2)
                     (function-no-numeric e list3)))
     (cons out (foo (rest list1) list2 list3))]))

(foo list1 list2 list3)

可能您想做其他事情,但结构应该类似于上面两个代码。例如,如果您碰巧真的需要一个索引来计算函数numeric和函数no numeric,您可以这样写:

(define (add10-all xs)
  (cond
    ;; a list is either empty, where (add10-all empty) should return empty
    [(empty? xs) empty]
    ;; or a cons, where we want to to add 10 to the first element, 
    ;; recur on the rest, and create a resulting cons
    [else (cons (+ 10 (first xs)) (add10-all (rest xs)))]))

;; (add10-all (list)) => (list)
;; (add10-all (list 2 3 4)) => (list 12 13 14)
;; assume function-numeric consumes (1) an element from list1 (2) the corresponding element in list2 (3) an index
;; assume function-no-numeric consumes (1) an element from list1 (2) the corresponding element in list3 (3) an index

(define (foo list1 list2 list3 i)
  (cond
    [(empty? list1) empty]
    [else
     (define e (first list1))
     (define out (if (number? e)
                     (function-numeric e (first list2) i)
                     (function-no-numeric e (first list3) i)))
     (cons out (foo (rest list1) (rest list2) (rest list3) (+ i 1)))]))

(foo list1 list2 list3 0)

如果你刚刚开始学习球拍,我真的建议你反对和赞成/列表。你应该首先了解基本的问题:什么是列表

也称为链表的列表是:

空的或 一个元素与另一个列表的组合 比如说,

empty是一个空列表。 cons 9 empty是一个列表 h一个要素:9。 cons 3 cons 9 empty是一个包含两个元素的列表:3和9。 给出一个列表,除了可以执行的cons之外,这里还有一些基本操作

空的lst:检查lst是否为空。例如,空的?empty计算为t但为空?cons 1的计算结果为f。 first lst:如果lst是cons,则返回lst的第一个元素。如果lst为空,则出错。例如,first cons 2 cons 1 empty计算为2,但first empty会导致错误。 rest lst:如果lst是cons,则返回lst的其余部分。如果lst为空,则出错。例如,rest cons 2 cons 1 empty计算为cons 1 empty,但第一个空会导致错误。 通过组合使用first和rest,您可以访问任何元素。如果列表cons 5 cons 4 cons 3 cons 2为空,并且您希望访问第二个元素,该元素应为4,您将计算:

剩余lst将为您提供cons 4 cons 3 cons 2空 第一个休息的lst将给你4。 list是一个简单的缩写,用于轻松构建列表

list是empty的缩写。 列表9是cons 9 empty的缩写 列表1 2 3是cons 1 cons 2 cons 3 empty的缩写。 其他列表操作仅使用上述基本操作实现。例如,list ref的实现如下所示:

(define (my-list-ref xs i)
  (cond
    ;; a list is either empty
    [(empty? xs) (error 'out-of-bound)]
    ;; or a cons, where it's safe to use first and rest
    [(= i 0) (first xs)]
    [else (my-list-ref (rest xs) (- i 1))]))

;; (my-list-ref (list) 0) => out-of-bound error
;; (my-list-ref (list 4 5 6) 0) => 4
;; (my-list-ref (list 4 5 6) 1) => 5
;; (my-list-ref (list 4 5 6) 2) => 6
正如奥斯卡·洛佩斯所提到的,虽然列表看起来类似于数组,但思考它们的方式却大不相同。使用list ref需要Oi,如果您想获得第i个元素一次,这很好,但这不是访问所有元素甚至很多元素的正确方法。相反,只需一次访问所有这些文件。例如,如果我有一个列表2 3 4,并且我想获得另一个列表,在原始列表的每个元素中添加10,我会写:

(define (add10-all xs)
  (cond
    ;; a list is either empty, where (add10-all empty) should return empty
    [(empty? xs) empty]
    ;; or a cons, where we want to to add 10 to the first element, 
    ;; recur on the rest, and create a resulting cons
    [else (cons (+ 10 (first xs)) (add10-all (rest xs)))]))

;; (add10-all (list)) => (list)
;; (add10-all (list 2 3 4)) => (list 12 13 14)
;; assume function-numeric consumes (1) an element from list1 (2) the corresponding element in list2 (3) an index
;; assume function-no-numeric consumes (1) an element from list1 (2) the corresponding element in list3 (3) an index

(define (foo list1 list2 list3 i)
  (cond
    [(empty? list1) empty]
    [else
     (define e (first list1))
     (define out (if (number? e)
                     (function-numeric e (first list2) i)
                     (function-no-numeric e (first list3) i)))
     (cons out (foo (rest list1) (rest list2) (rest list3) (+ i 1)))]))

(foo list1 list2 list3 0)
在您的情况下,您可能需要:

;; assume function-numeric consumes an element from list1 and the whole list2
;; assume function-no-numeric consumes an element from list1 and the whole list3

(define (foo list1 list2 list3)
  (cond
    [(empty? list1) empty]
    [else
     (define e (first list1))
     (define out (if (number? e)
                     (function-numeric e list2)
                     (function-no-numeric e list3)))
     (cons out (foo (rest list1) list2 list3))]))

(foo list1 list2 list3)

可能您想做其他事情,但结构应该类似于上面两个代码。例如,如果您碰巧真的需要一个索引来计算函数numeric和函数no numeric,您可以这样写:

(define (add10-all xs)
  (cond
    ;; a list is either empty, where (add10-all empty) should return empty
    [(empty? xs) empty]
    ;; or a cons, where we want to to add 10 to the first element, 
    ;; recur on the rest, and create a resulting cons
    [else (cons (+ 10 (first xs)) (add10-all (rest xs)))]))

;; (add10-all (list)) => (list)
;; (add10-all (list 2 3 4)) => (list 12 13 14)
;; assume function-numeric consumes (1) an element from list1 (2) the corresponding element in list2 (3) an index
;; assume function-no-numeric consumes (1) an element from list1 (2) the corresponding element in list3 (3) an index

(define (foo list1 list2 list3 i)
  (cond
    [(empty? list1) empty]
    [else
     (define e (first list1))
     (define out (if (number? e)
                     (function-numeric e (first list2) i)
                     (function-no-numeric e (first list3) i)))
     (cons out (foo (rest list1) (rest list2) (rest list3) (+ i 1)))]))

(foo list1 list2 list3 0)

我不知道first和rest,我一直使用car和cdr。加上我总是使用空值?我不知道first和rest,我一直使用car和cdr。加上我总是使用空值?有时,有必要用一种不熟悉的语言编程,并将其弯曲成熟悉的形状。遗留代码、平台细节等,但您暗示您想学习racket。你不能把它变成C的导数。如果你坚持的话,你可以用这种方式编程,有时出于性能原因,这是必要的,但你不会学。有时,有必要用一种不熟悉的语言编程,并将其弯曲成熟悉的形状。遗留代码、平台细节等,但您暗示您想学习racket。你不能把它变成C的导数。如果您坚持的话,您可以用这种方式编程,有时出于性能原因,这是必要的,但您不会学习。我尝试了您建议的方法:使用索引生成一个单独的列表,我使用map,但map遍历第一个列表,然后遍历第二个列表。这听起来不对。你怎么称呼它的?如果您这样做:映射lambda e1 e2执行某些操作lst1 lst2它将同时遍历两个列表。这就是我所做的:定义lst1'1 2 3 4,映射lambda e1 e2显示e1 lst1范围0长度lst1。我得到:1234’。也许我还不明白发生了什么。地图不是这样工作的,你使用的lambda必须返回一些东西。display只是在控制台中打印一个值,然后返回。将显示调用替换为:list e1 e2,您将看到它工作正常。是的,这比使用for/list(仅在Racket中工作)更便于移植。我尝试了您建议的方法:使用索引生成单独的列表,我使用map,但map遍历第一个列表,然后遍历第二个列表。这听起来不对。你怎么称呼它的?如果您这样做:映射lambda e1 e2执行某些操作lst1 lst2它将同时遍历两个列表。这就是我所做的:定义lst1'1 2 3 4,映射lambda e1 e2显示e1 lst1范围0长度lst1。我得到:1234’。也许我还不明白发生了什么。地图不是这样工作的,你使用的lambda必须返回一些东西。display只是在控制台中打印一个值,然后返回。将显示调用替换为:list e1 e2,您将看到它工作正常。是的,这比使用for/list(仅在Racket中工作)更方便。