1
votes

Résumer une liste à l'aide de la macro Dolist

J'essayais de résumer une liste en utilisant la macro dolist. Mais je ne pouvais pas le faire. Il renvoie toujours le dernier élément de la liste. Merci d'avance.

(defun sumlist2 (l)
  ;;this function computes total of a list by using dolist macro
  (let ((summ 0))
    (dolist (obj l)
      (setf summ (+ obj)))
    summ))


1 commentaires

FYI et collègues googleurs, sommation avec boucle et série: lispcookbook.github.io/cl -cookbook / iteration.html # summation


4 Réponses :


7
votes

Dans le corps de dolist , vous ne somme pas une valeur à la variable summ , mais lui assignez la valeur de l'élément de la liste, puisque (+ obj) additionne obj sans autre valeur et renvoie donc obj lui-même. En d'autres termes, au lieu de:

(defun sumlist2 (l)
  ;;this function computes total of a list by using dolist macro
  (let ((summ 0))
    (dolist (obj l summ)
      (incf summ obj))))

vous devriez écrire:

(incf summ obj)

ou, mieux encore:

(setf summ (+ summ obj))

qui effectue l'addition.

Enfin, notez que vous pouvez produire un résultat directement à partir de dolist , comme dans:

(setf summ (+ obj))


0 commentaires

5
votes

La fonction + en Lisp est immuable, elle calcule juste une nouvelle valeur:

(incf summ obj)

Dans votre code, vous setf le variable locale summ avec chaque valeur extraite de la liste. Finalement, il ne contient que la dernière valeur de la liste. Si vous souhaitez mettre à jour summ , vous devez faire:

(setf summ (+ summ obj))

Ou, simplement:

(+)         is zero
(+ x)       is just x
(+ x y ...) is the sum of x, y, etc.


0 commentaires

2
votes

Pour info avec loop:

(reduce #'+ '(1 2 3))

also

(loop for i in '(1 2 3) sum i)
;; 6

voir plus: https://lispcookbook.github.io/cl-cookbook/iteration.html#summation


0 commentaires

0
votes

Ci-dessous, j'ai un exemple de fonction qui peut fonctionner pour vous, puis je vais expliquer votre erreur:

(sum-list ‘(1 2 3 4 5 6 7))
28

Au lieu de:

(setf sum (+ obj))

Nous ajoutons la somme de la liste que nous avons déjà acquise dans l'itération précédente au numéro de la liste que nous parcourons actuellement:

(defun sum-list(lst)
  (let((sum 0))
    (dolist(l lst)
      (setf sum (+ sum l)))
     sum))

Ci-dessous, nous pouvons passer une liste des entiers 1 à 7 qui renverra une valeur de 28.


0 commentaires