如何解决在 Racket 中寻找“地图”的说明
stackoverflow 的新手和球拍的新手。我一直在使用以下文档学习球拍:https://docs.racket-lang.org/reference/pairs.html
这是我对地图的理解:
(map (lambda (number) (+ 1 number))'(1 2 3 4))
这将 '(1 2 3 4)
分配给变量 number
,然后 map 执行 (+ 1 '(1 2 3 4))
。
但是当我看到以下内容时:
(define (matrix_addition matrix_a matrix_b)
(map (lambda (x y) (map + x y)) matrix_a matrix_b))
我很迷茫。我假设我们正在分配两个变量 x
和 y
,然后执行 (map + x y)
,但我不明白 (map + x y)
是什么或如何工作。
我遇到的另一个问题是
(define (matrix_transpose matrix_a)
(apply map (lambda x x) matrix_a))
(lambda x x)
到底是做什么的?
非常感谢您的澄清。如您所见,我一直在按照我朋友的建议进行矩阵运算。
解决方法
这是考虑 map
的一种方式:
(map f (list 1 2 3)) computes (list (f 1) (f 2) (f 3)).
和
(map f (list 1 2 3) (list 11 22 33)) computes (list (f 1 11) (f 2 22) (f 3 33)).
所以您的 +
示例变为:
(map + (list 1 2 3) (list 11 22 33)) computes (list (+ 1 11) (+ 2 22) (+ 3 33))
这是(list 12 24 36)
。
开头写的比较清楚
(define f (lambda (x y) (+ x y)))
(map f (list 1 2 3) (list 11 22 33)))
但是当你习惯了 map
和 lambda
时,速记
(map (lambda (x y) (+ x y)) (list 1 2 3) (list 11 22 33)))
很有用。
,这将 '(1 2 3 4)
分配给变量 number
,然后 map
执行 (+ 1 '(1 2 3 4))
。
不,这不是它的作用。 map
是一个循环函数,它对列表中的每个元素分别调用该函数,并返回一个结果列表。
所以它首先将 number
绑定到 1
并执行 (+ 1 number)
,也就是 (+ 1 1)
。然后它将 number
绑定到 2
并执行 (+ 1 number)
,即 (+ 1 2)
。等等。所有结果都收集到一个列表中,因此它返回 (2 3 4 5)
。
开始进行矩阵运算,矩阵表示为列表列表,因此我们需要嵌套循环,这是使用对 map
的嵌套调用完成的。
(map (lambda (x y) (map + x y)) matrix_a matrix_b)
外层map
的工作原理如下:首先将x
和y
分别绑定到matrix_a
和matrix_b
的第一个元素,并执行{{ 1}}。然后将 (map + x y)
和 x
绑定到 y
和 matrix_a
的第二个元素,并执行 matrix_b
。对两个列表的每个元素依此类推。最后它返回所有这些结果的列表。
内部 (map + x y)
将两个列表的相应元素相加,返回总和列表。例如。 (map + x y)
返回 (map + '(1 2 3) '(4 5 6))
。
因此,这将创建一个列表列表,其中每个元素是 (5 7 9)
和 matrix_a
的相应元素的总和。
最后,
matrix_b
到底是做什么的?
它将 (lambda x x)
绑定到所有参数的列表,并返回该列表。所以 x
返回列表 ((lambda x x) 1 2 3 4)
。它基本上是 (1 2 3 4)
的反函数,它将列表扩展为函数的多个参数。
apply
返回 (apply (lambda x x) some-list)
的副本。
这将 '(1 2 3 4) 分配给变量 number ,然后 map 执行 (+ 1 '(1 2 3 4))。
如果就这么简单,为什么需要map
。您可以直接执行 (+ 1 '(1 2 3 4))
。这是 map1
的一个实现,它是 map
,它只能有一个列表参数:
(define (map1 fn lst)
(if (empty? lst)
empty
(cons (fn (first lst))
(map1 f (rest lst)))))
它的作用:
(map1 add1 '(1 2 3))
; ==> (cons (add1 1) (cons (add1 2) (cons (add1 3) empty)))
; same as (list (add1 1) (add1 2) (add1 3))
真正的 map
接受任意数量的列表参数,然后期望 element 函数采用与列表参数一样多的元素。例如。
(map (lambda (l n s) (list l n s)) '(a b c) '(1 2 3) '($ % *))
; ==> ((a 1 $) (b 2 %) (c 3 *))
在不知道元素数量的情况下执行此操作的一种非常酷的方法是 unzip
(define (unzip . lst)
(apply map list lst))
(unzip '(a b c) '(1 2 3) '($ % *))
; ==> ((a 1 $) (b 2 %) (c 3 *))
所以 apply
对 (map list '(a b c) '(1 2 3) '($ % *))
的调用变平,list
接受任意元素,因此它的工作方式与上一个示例相同,但它也适用于其他维度:
(unzip '(a b c d) '(1 2 3 4))
; ==> ((a 1) (b 2) (c 3) (d 4))
,
map
的第一个参数是一个函数。此函数可能需要一个或多个参数。参数列表中的函数后面是一个或多个列表。
map
从列表的第一个元素到最后一个元素并行循环。
并因此将每个列表的第 i 个位置作为函数的参数
并将结果收集到它返回的结果列表中。
现在三个简短的例子可以让你清楚地图如何通过列表:
(map list '(1 2 3))
;; => '((1) (2) (3))
(map list '(1 2 3) '(a b c))
;; => '((1 a) (2 b) (3 c))
(map list '(1 2 3) '(a b c) '(A B C))
;; => '((1 a A) (2 b B) (3 c C))
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。