我有两个列表如下:
(x y z) & (2 1)
我希望得到一个结果:
((x y) (z))
列表的关系非常清楚。所以基本上我想把第一个列表的成员重新排列成一个列表,列表中有两个(第二个列表的长度)列表。 我尝试过两次dotimes迭代来做到这一点:
(let ((result) (list1* list1))
(dotimes (n (length list2) result)
(progn (setq result
(append result
(list (let ((result2))
(dotimes (m (nth n list2) result2)
(setq result2
(append result2
(list (nth m list1*)))))))))
(setq list1*
(subseq list1* 0 (nth n list2))))))
我的想法是我制作了预期结果的第一个列表(x y),然后我想更新(x y z)列表,以便删除x任何y,我只有(z)。然后循环再次运行以获得预期结果中的(z)列表。这不能正常工作并导致:
((x y) (x))
这意味着显然第二个基本更新list1 *的命令是不起作用的。显然,必须有一个正确和更好的方法来做到这一点,我想知道是否有人可以帮助解决这个问题。还解释为什么不能解释解决方案?
答案 0 :(得分:3)
如果我看到了这一点,那么您的问题就在(subseq list1* 0 (nth n list2))
,它会返回您不想要的列表部分。
我提供以下内容:
(defun partition-list (list lengths)
(mapcar (lambda (length)
(loop :repeat length
:collect (pop list)))
lengths))
当然,这有点过于简单,因为它不处理意外输入,例如(length list)
小于(reduce #'+ lengths)
,但它可以扩展。
答案 1 :(得分:1)
仅为示例,使用iterate
:
(defun partition-list (list by)
(iter:iter
(iter:for element in list)
(iter:for i from 1)
(iter:generating measure in by)
(iter:collect element into sublist)
(when (= (or measure (iter:next measure)) i)
(iter:collect sublist)
(iter:next measure)
(setf i 0 sublist nil))))