方案循环不会遍历列表中的所有元素

Posted

技术标签:

【中文标题】方案循环不会遍历列表中的所有元素【英文标题】:scheme loop does not iterate through all elements in the list 【发布时间】:2020-11-16 16:20:40 【问题描述】:

我正在尝试根据条件更改列表中的元素。假设我有一个清单, L = '(0 1 1 0 0)。我只希望在此列表中找到的第一个“零”为“零”,对于该列表中的任何其他“零”,我希望它们为 1。因此我的示例列表将变为 L = '(0 1 1 1 1)。这是我到目前为止所做的,

(let dLoop ((L '(0 1 1 0 0))
            (i 0)
            (j 1))
  (if (and (<= i (length L)) (<= j (- (length L) 1)))
      (begin
        (if (zero? (list-ref L i))
            (begin
              (cond
                [(zero? (list-ref L j)) (list-set L j 1)]
                [else (dLoop L i (add1 j))]
                )
              )
            (dLoop L (add1 i) (add1 j))))
      L))

这只会返回,L = '(0 1 1 1 0)

由于某种原因,一旦找到第一个重复的零,代码就会终止!我真的很感激有关此问题的一些见解

【问题讨论】:

也许你可以使用cdrcons,而不是像在C中那样迭代循环;一种更常见于 lisps 的方法。 【参考方案1】:

在您的 (cond) 表达式中,如果 (zero? (list-ref L j)) case 求值,则您没有对 dLoop 的递归调用。这会导致 (cond) 返回,然后 (begin) 返回并最终退出 you (let) 表达式。然而,除了 Lazer 所说的,这有点不是标准的方案方法,更不用说非常有效了,因为链表上的 (list-ref) 每次都是 O(n)。也许尝试类似:

(define (find-and-map-rest lst pred f)
  (cond [(null? lst) lst]
        ;; found the thing
        [(pred (car lst)) (cons (car lst)
                                (map f (cdr lst)))]
        ;; didn't find the thing... yet
        [else (cons (car lst)
                    (find-and-map-rest (cdr lst)
                                       pred f))]))


(define (zero->one x)
   (if (zero? x) 1 x))

(find-and-map-rest '(0 1 1 0 0) zero? zero->one)

【讨论】:

【参考方案2】:

对于这样的任务,现实的代码可能无法完成consing 的所有工作。代码真正需要做的就是找到第一个零,取列表的第一部分直到并包括该零,然后将其附加到与输入列表的其余部分一样长的一列中。如果没有找到零,则结果只是输入列表:

(define (f xs)
  (let ((rest (member 0 xs)))
    (if rest
        (let ((ones-count (sub1 (length rest))))
          (append (take xs (- (length xs) ones-count))
                  (make-list ones-count 1)))
        xs)))

示例交互:

scratch.rkt> (f '(0))
'(0)
scratch.rkt> (f '(1))
'(1)
scratch.rkt> (f '(0 1 1 0 0))
'(0 1 1 1 1)
scratch.rkt> (f '(1 1 0 1 1 1 0 0 1 0 1 0))
'(1 1 0 1 1 1 1 1 1 1 1 1)

【讨论】:

以上是关于方案循环不会遍历列表中的所有元素的主要内容,如果未能解决你的问题,请参考以下文章

为啥带有pop-method(或del语句)的for循环不会遍历所有列表元素

python列表的遍历与循环

操作列表

循环遍历 pandas 数据框列中的列表元素以在新列中返回列表

迭代Python列表中的每两个元素[重复]

ast.literal_eval - 循环遍历列表中的字符串元素