将列表中的每个元素与另一个列表中的每个元素相乘lisp
问题描述:
我想写一个函数,它接受2个列表作为参数并返回列表中的乘积。 这样的:将列表中的每个元素与另一个列表中的每个元素相乘lisp
(3 4)(3 5 6)=>(9 15 18 12 20 24)
这是我已经想出了的代码,但我接收被告知错误我对地图的论据太少了。
(defun multip (lst lst2)
;this is a function to flatten the result
(defun flatten (tree)
(let ((result '()))
(labels ((scan (item)
(if (listp item)
(map nil #'scan item)
(push item result))))
(scan tree))
(nreverse result)))
(flatten (map (lambda (i) (map (lambda (j) (* i j)) lst)) lst2))
)
(write (multip '(3 4 6) '(3 2)))
我不明白我做错了什么。我感谢你的评论。
答
您应该使用mapcar
,而不是map
:
(mapcar (lambda (i) (mapcar (lambda (j) (* i j)) lst)) lst2))
这是两个不同的功能:mapcar
地图上的一个或多个列表的功能,至少需要两个参数,而map
是等效的,但是任何序列类型(例如向量),并且需要额外的参数来指定结果的类型。请参阅参考文献map
here,并参考mapcar
here。
风格
您使用的是defun
内的另一个defun
:这是不好的风格,因为每一次multip
被称之为全球重新定义了功能flatten
。您应该定义flatten
外,只有一次,或使用功能的局部声明与flet
或labels
(作为内部功能scan
内flatten
。)
对于flatten
另一种更简单的定义,你可以看到this question所以。
答
如果您创建一个扁平列表,则不需要扁平化列表。
使用MAPCAN:
CL-USER 4 > (flet ((mult (a b)
(mapcan #'(lambda (a1)
(mapcar (lambda (b1) (* a1 b1))
b))
a)))
(mult '(3 4) '(3 5 6)))
(9 15 18 12 20 24)
仅供参考,您可以使用使用地图产品:'(亚历山大:地图产品# '*'(3 4)“(3 5 6))' – coredump