为什么这些都打印相同的东西?

为什么这些都打印相同的东西?

问题描述:

我真的很好奇,为什么使用“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从输出的第二部分被删除,但它不会,除非我宣布它在一个变量。我怎样才能处理单个数据并在不声明大量变量的情况下删除/添加需要的数据?

+2

为什么大多数变量是未定义的?例如'first-char'?它在哪里定义?你为什么要调用'remove',但从不使用结果?什么是变量'first-char'?它没有用过?函数'last'返回什么? –

+0

因为它不完整,我碰到了一个绊脚石,这是我的问题,我只是添加了所有的代码,以便更容易理解上下文。 – Floofk

(我认为这将之前已经问过了,当然也有对堆栈溢出有关的东西,但我没有找到一个合适的重复。)

的问题是,删除返回一个新的列表;它不会修改现有的列表。从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单元。想了解更多,请参阅,例如:


另外值得一提的是,许多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" 
+0

谢谢你的回答:D你如何做猪拉丁函数的例子已经越过了我的头,当我到达它的时候,我会穿过那座桥。谢谢! – Floofk