2

I need to produce a list containing the averages of a lists of lists where the number of sub-lists could vary. So given the input list:

((l1a l1b l1c) (l2a l2b l2c) (l3a l3b l3c)...)

the output would be:

(average(l1a l2a l3a) average(l1b l2b l3b) average(l1c l2c l3c)...).

I'm sure there's a really elegant way to do this in lisp but I don't know where to start. Any advice would be gratefully received.

7
  • It looks like you just need to map. I don't know CL, but I do know Clojure, which is another lisp. If your lists are bound to a symbol lists, you'd just do, in Clojure, (map average lists). I'm sure it's very similar in CL. Commented Nov 18, 2018 at 21:35
  • That's it! Thank you. I knew there would be an easy way but wasn't aware of the map function. In CL to do that using add for example you would simply use: (map 'list #'+ '(1 2 3) '(1 2 3) '(1 2 3)) Commented Nov 18, 2018 at 21:51
  • Np. And if you're just starting into functional programming, make sure you have a very good understanding of map and reduce/fold (I don't know what CL calls it). Those are bread-and-butter functions that you'll likely be using regularly. Commented Nov 18, 2018 at 22:01
  • Carcinegate is correct. You need to define an average function that takes a list as a parameter then pass it to mapcar . The syntax is different from Clojure - use (mapcar #'average list) where average is the function you define. The average function should use reduce to sum the list. Commented Nov 18, 2018 at 22:09
  • Got it - thank you. (defun average (lst) (/ (reduce #'+ lst) (length lst))) and then (mapcar #'average '((50 23 35) (60 12 34) (70 52 38))) Commented Nov 18, 2018 at 22:43

1 Answer 1

6
CL-USER 27 > (let* ((list-of-lists '((1.0 2.0 3.0)
                                     (1.0 3.0 5.0)
                                     (1.0 4.0 6.0)
                                     (1.0 5.0 8.0)))
                    (length (length list-of-lists)))
               (mapcar (lambda (x)
                         (/ x length))
                       (reduce (lambda (l1 l2)
                                 (mapcar #'+ l1 l2))
                               list-of-lists)))
(1.0 3.5 5.5)
Sign up to request clarification or add additional context in comments.

1 Comment

Yes, I realised it was wrong when I just tried to apply my solution to my problem. Many thanks for your solution Rainer.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.