我真的很好奇为什么要使用"删除"实际上它不是从列表中删除的,如果我在一个变量中声明它,但是我有另一个变量可以使用它并且它变得非常混乱,他是我的代码;
;;;;Pig latin
(defun pig-latin ()
(let ((word (read-line)))
(setf ind-characters (loop for char across word
collect char))
(setf first-char (car ind-characters))
(setf reversed-word (reverse ind-characters));flips the
(remove (last reversed-word) reversed-word)
(print reversed-word)))
我得到的输出是:
(#\d #\r #\o #\w)
(#\d #\r #\o #\w)
我原本希望从输出的第二部分删除#\ w,但除非我在变量中声明它,否则它不会被删除。如何在不声明大量变量的情况下处理单个数据并删除/添加我需要的数据?
答案 0 :(得分:7)
(我以为之前会问过这个问题,Stack Overflow肯定有相关内容,但我没有找到合适的副本。)
问题是删除会返回一个新列表;它不会修改现有列表。来自remove的HyperSpec条目的相关部分(强调添加):
remove,remove-if,remove-if-not返回与之类型相同的序列 具有相同元素的序列,除了那些元素 由开始和结束限制并满足测试的子序列 除去。 这是一种非破坏性的操作。如果有任何要素需要 被删除,结果将是一个副本。删除的结果可能会共享 顺序;如果没有,结果可能与输入序列相同 需要删除元素。
这意味着您需要使用删除返回的值。例如,您可以将其返回,将其绑定到变量,或将其分配给变量:
(defun remove-1 (list)
(remove 1 list)) ; return the result
(let ((list-without-ones (remove 1 list))) ; bind the result
...)
(setf list (remove 1 list)) ; update a variable
请注意,该语言还包含删除功能,该功能可能具有破坏性。但请注意,这并不能消除保存结果的需要。这意味着可以修改列表结构。但是,您仍然需要保存结果,因为旧列表中第一个的cons单元可能不是新列表中第一个的cons单元。有关此内容的更多信息,请参阅:
还值得注意的是,许多Common Lisp函数在序列上运行,而不仅仅是列表。序列包括向量,其中字符串是子类型。例如,(反向"单词")将返回" drow" 。同样,您可以在序列上使用 position-if 。这意味着可以通过以下方式完成简单的猪拉丁功能:
(defun vowelp (char)
(position char "aeiou" :test 'char-equal))
(defun pig-latin (word)
(let ((i (position-if 'vowelp word))) ; position of first vowel
(if (null i) word ; if no vowels, return word
(concatenate 'string ; else, concatenate parts:
(subseq word i) ; * "ord"
(subseq word 0 i) ; * "w"
"ay")))) ; * "ay"