我想写一个接受2个列表作为参数的函数,并在列表中返回它们的乘法。 像这样:
(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) ))
我无法理解我做错了什么。感谢您的评论。
答案 0 :(得分:4)
如果您创建一个单位列表,则不需要展平列表。
使用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)
答案 1 :(得分:3)
您应该使用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
的替代和更简单的定义,您可以在SO中看到this question。