为什么这些都打印相同的东西?
我真的很好奇,为什么使用“remove”实际上并没有从列表中删除,如果我将它声明在一个变量中,但是我有另一个变量可以使用,并且它变得非常混乱,他是我的码;为什么这些都打印相同的东西?
;;;;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从输出的第二部分被删除,但它不会,除非我宣布它在一个变量。我怎样才能处理单个数据并在不声明大量变量的情况下删除/添加需要的数据?
(我认为这将之前已经问过了,当然也有对堆栈溢出有关的东西,但我没有找到一个合适的重复。)
的问题是,删除返回一个新的列表;它不会修改现有的列表。从HyperSpec条目remove相关部分(强调):
删除,删除-如果,除去-IF-不返回相同类型的序列为具有不同的是那些在相同的元件 序列 子序列以开始和结束为界,满足测试已被删除 。 这是一个非破坏性的操作。如果有任何元素需要删除,则结果将是副本。删除的结果可能与序列共享 ;如果没有 元素需要删除,结果可能与输入序列相同。
这意味着你需要使用返回的值删除。例如,你可以返回它,它绑定到一个变量,或将其分配给一个变量:
(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单元。想了解更多,请参阅,例如:
- Destructive sorting in lisp
- DELETE is destructive -- but not always?
- Common Lisp: is delete-if the same as setf + remove-if?
另外值得一提的是,许多Common Lisp的功能上序列,无法操作只是列表。序列包括矢量,其中的字符串是一个子类型。例如,(反向“单词”)将返回“卓尔”。同样,您可以使用位置 - 如果在序列上。这意味着一个简单的拉丁函数可以用类似这样的方法完成:
(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"
谢谢你的回答:D你如何做猪拉丁函数的例子已经越过了我的头,当我到达它的时候,我会穿过那座桥。谢谢! – Floofk
为什么大多数变量是未定义的?例如'first-char'?它在哪里定义?你为什么要调用'remove',但从不使用结果?什么是变量'first-char'?它没有用过?函数'last'返回什么? –
因为它不完整,我碰到了一个绊脚石,这是我的问题,我只是添加了所有的代码,以便更容易理解上下文。 – Floofk