1

我有两个列表如下:

(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))))))

这个想法是我制作了预期结果(xy)的第一个列表,然后我想更新(xyz)列表,以便删除 x 任何 y 并且我只有(z)。然后循环再次运行以获得预期结果中的 (z) 列表。这不能正常工作并导致:

 ((x y) (x))

这显然意味着基本上更新 list1* 的 progn 的第二个命令不起作用。显然,必须有一个正确和更好的方法来做到这一点,我想知道是否有人可以提供帮助。还要解释为什么无法解释解决方案?

4

2 回答 2

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),但可以对其进行扩展。

于 2013-07-15T17:31:55.747 回答
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))))
于 2013-07-15T18:36:00.593 回答