【问题标题】:List operations in LispLisp 中的列表操作
【发布时间】:2010-09-07 21:31:06
【问题描述】:

我一直在到处寻找 Lisp 中的以下功能,但一无所获:

  1. 在列表中查找某项的索引。示例:

    (index-of item InThisList)
    
  2. 替换列表中特定位置的内容。示例:

    (replace item InThisList AtThisIndex) ;i think this can be done with 'setf'?
    
  3. 返回特定索引处的项目。示例:

    (return InThisList ItemAtThisIndex)
    

到目前为止,我一直在用我自己的函数来伪装它。我想知道我是否只是在为自己创造更多的工作。

这就是我一直在伪装数字 1:

(defun my-index (findMe mylist)
  (let ((counter 0) (found 1))
    (dolist (item mylist)
      (cond
        ((eq item findMe) ;this works because 'eq' checks place in memory, 
                  ;and as long as 'findMe' was from the original list, this will work.
         (setq found nil)
        (found (incf counter))))
  counter))

【问题讨论】:

    标签: functional-programming lisp list


    【解决方案1】:

    您可以使用setfnth 按索引替换和检索值。

    (let ((myList '(1 2 3 4 5 6)))
         (setf (nth 4 myList) 101); <----
         myList)
    
    (1 2 3 4 101 6)
    

    要按索引查找,您可以使用the position function

    (let ((myList '(1 2 3 4 5 6)))
         (setf (nth 4 myList) 101)
         (list myList (position 101 myList)))
    
    ((1 2 3 4 101 6) 4)
    

    这些我都找到了in this index of functions

    【讨论】:

      【解决方案2】:
      1. 在列表中查找某项的索引。

      在 Emacs Lisp 和 Common Lisp 中,你有 position 函数:

      > (setq numbers (list 1 2 3 4))
      (1 2 3 4)
      > (position 3 numbers)
      2
      

      在 Scheme 中,这是来自 DrScheme 的文档的尾递归实现:

      (define list-position 
        (lambda (o l)
          (let loop ((i 0) (l l))
            (if (null? l) #f
                (if (eqv? (car l) o) i
                    (loop (+ i 1) (cdr l)))))))
      
      ----------------------------------------------------
      
      > (define numbers (list 1 2 3 4))
      > (list-position 3 numbers)
      2
      > 
      

      但是,如果您使用列表作为插槽集合来存储结构化数据,也许您应该看看defstruct 甚至是某种 Lisp 对象系统,如 CLOS。

      如果您正在学习 Lisp,请务必查看 Practical Common Lisp 和/或 The Little Schemer

      干杯!

      【讨论】:

        【解决方案3】:

        +2 表示“实用通用 Lisp”。它是 Common Lisp Cookbook 和优质的 Teach Yourself Lisp 书籍的混合体。

        还有“成功的 Common Lisp”(http://www.psg.com/~dlamkins/sl/cover.htmlhttp://www.psg.com/~dlamkins/sl/contents.html)似乎填补了“实用 Common Lisp”中的一些空白/扩展了一些东西。

        我还阅读了 Paul Graham 的“ANSI Common Lisp”,它更多地介绍了语言的基础知识,但更多的是参考手册。

        【讨论】:

          【解决方案4】:

          答案:

          1. (位置项序列&key from-end (start 0) end key test test-not)
            http://lispdoc.com/?q=position&search=Basic+search

          2. (setf(elt序列索引)值)

          3. (elt序列索引)
            http://lispdoc.com/?q=elt&search=Basic+search
            注意:elt 比 nth 更可取,因为 elt 适用于任何序列,而不仅仅是列表

          【讨论】:

            【解决方案5】:

            我必须同意托马斯的观点。如果您使用像数组这样的列表,那只会很慢(并且可能很尴尬)。因此,您应该使用数组或坚持使用您编写的函数,但将它们“向上”移动,以便您以后可以轻松地用数组替换慢速列表。

            【讨论】:

              【解决方案6】:

              杰里米的答案应该有效;但这就是说,如果您发现自己正在编写类似的代码

              (setf (nth i my-list) new-elt)

              您可能使用了错误的数据结构。列表只是简单的链表,因此按索引访问它们是 O(N)。使用数组可能会更好。

              或者您可能正在使用列表作为元组。在这种情况下,他们应该没问题。但是您可能想要命名访问器,这样阅读您的代码的人就不必记住“nth 4”应该是什么意思。类似的东西

              (defun my-attr (list)
                (nth 4 list))
              
              (defun (setf my-attr) (new list)
                (setf (nth 4 list) new))
              

              【讨论】:

              • 另外,我们不会“替换”列表中的元素。我们正在复制第一个 (r-1) 元素并将新值放入 r,其中 cdr 连接到 (r+1) 元素——因为我们正在处理持久性。
              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 2011-07-10
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2021-04-01
              相关资源
              最近更新 更多