将列表中的每个元素与lisp中另一个列表的每个元素相乘

时间:2016-11-13 07:57:14

标签: lisp common-lisp multiplying

我想写一个接受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) ))

我无法理解我做错了什么。感谢您的评论。

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,只定义一次,或者使用fletlabels的本地函数声明(对于scan内的内部函数flatten 。)

对于flatten的替代和更简单的定义,您可以在SO中看到this question