我正在尝试将对子列表作为家庭作业的一部分。
我尝试过(在函数中间某处)
(setq list1 (append list1 (cons n1 n2)))
由于某些原因我不明白,这对第一对很好,但是当我尝试追加第二对时,会弹出这个错误:
*** - APPEND:正确的列表不得以2
结尾
我该如何解决这个问题?
所以,继续这个主题,感谢答案,我能够纠正我的问题。但是出现了一个新的,我认为它与它有关。所以,我有这个功能:
(defun action(state)
(let ((list_actions '())
(limNumActions (1- (list-length state)))
(limNumSubActions 0)
(numActions 0)
(numSubActions 0))
(loop for numActions from 0 to limNumActions do
(setq limNumSubActions (1- (list-length (nth numActions state))))
(loop for numSubActions from 0 to limNumSubActions do
(setq list_actions (append list_actions
(list (cons numActions numSubActions))))
(print 'list_actions)
(print list_actions)))))
我使用print
函数作为简单的“调试器”。它返回:
LIST_ACTIONS
((0 . 0))
LIST_ACTIONS
((0 . 0) (0 . 1))
LIST_ACTIONS
((0 . 0) (0 . 1) (1 . 0))
LIST_ACTIONS
((0 . 0) (0 . 1) (1 . 0) (1 . 1))
NIL
这正是我期待的结果! NIL
部分除外...您能否理解为什么列表list_actions
最后是NIL
?
答案 0 :(得分:1)
append
有两个列表,不是列表和单个元素。在append
中使用它之前,您需要在对中放置一个列表。
目前该对被列为列表的一部分,这使得列表不正确并导致第二个附加失败,因为不正确的列表没有完全附加到的结尾。
答案 1 :(得分:1)
代码可以更加简洁地表达如下:
(defun action (state)
(let ((list-actions '()))
(loop for i from 0 for state-i in state do
(loop for j from 0 below (length state-i) do
(setf list-actions (append list-actions (list (cons i j))))
(print 'list-actions)
(print list-actions)))
list-actions))
如果只需要结果,它可以更短(并且成本更低,因为它不使用昂贵的append
功能),
(defun action (state)
(loop for i from 0 for state-i in state append
(loop for j below (length state-i) collect (cons i j))))
答案 2 :(得分:0)
我试图稍微改进你的例子+编写一个使用不同的版本,但IMO更习惯于解决这个问题:
;; Your original version, but cleaned up a bit
(defun action (state)
(loop with list-actions = nil
with lim-num-actions = (1- (list-length state))
with lim-num-sub-actions = 0
for num-actions from 0 to lim-num-actions
do (setq lim-num-sub-actions (1- (list-length (nth num-actions state))))
(loop for num-sub-actions from 0 to lim-num-sub-actions
do (push (cons num-actions num-sub-actions) list-actions)
(format t "~&~s ~s" 'list-actions list-actions))
finally (return list-actions)))
;; A more traditional approach (if you want to use iteration)
(defun action (state)
(reverse
(loop for i in state
for j from 0
collect (cons j 0))))
;; Using a nice library to do iteration
(ql:quickload "iterate")
;; Note, you could do (in-package :iterate)
;; to lose `iterate:' prefix to make it even shorter
(defun action (state)
(iterate:iter
(iterate:for i #:on state)
(iterate:for j #:from 0)
(iterate:accumulate (cons j 0) #:by #'cons)))
;; Just another way to do this, using `reduce'
(reduce #'(lambda (a b)
(declare (ignore b))
(cons (cons (1+ (caar a)) 0) a))
(cdr (mapcar #'list '(1 2 3 4 5)))
:initial-value '((0 . 0)))
(action (mapcar #'list '(1 2 3 4 5)))