为什么这两个打印相同的东西?
Why do these both print the same thing?
我真的很好奇为什么使用 "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 会从输出的第二部分中删除,但除非我在变量中声明它,否则不会。如何在不声明大量变量的情况下只处理单个数据和 remove/add 我需要的数据?
(我还以为这个以前会有人问过,Stack Overflow上肯定有相关的东西,但是我没有找到合适的副本。)
问题是删除 return一个新列表;它不会修改 现有列表。 remove 的 HyperSpec 条目中的相关部分(强调已添加):
remove, remove-if, remove-if-not return a sequence of the same type as
sequence that has the same elements except that those in the
subsequence bounded by start and end and satisfying the test have been
removed. This is a non-destructive operation. If any elements need to
be removed, the result will be a copy. The result of remove may share
with sequence; the result may be identical to the input sequence if no
elements need to be removed.
这意味着您需要使用 return 通过 删除 编辑的值。例如,您可以 return 它,将它绑定到一个变量,或者将它分配给一个变量:
(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
请注意,该语言还包含一个 delete 函数,该函数可能具有破坏性。但是请注意,这并不能消除保存结果的需要。这意味着可以修改列表结构。不过,您仍然需要保存结果,因为旧列表中第一个的 cons 单元可能不是新列表中第一个的 cons 单元。有关更多信息,请参见,例如:
- DELETE is destructive -- but not always?
- Common Lisp: is delete-if the same as setf + remove-if?
还值得注意的是,许多 Common Lisp 函数在 序列 上运行,而不仅仅是列表。序列包括向量,字符串是向量的一个子类型。例如,(反向 "word") 将 return "drow"。同样,您可以在序列上使用 position-if。这意味着一个简单的 pig latin 函数可以像这样完成:
(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"
我真的很好奇为什么使用 "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 会从输出的第二部分中删除,但除非我在变量中声明它,否则不会。如何在不声明大量变量的情况下只处理单个数据和 remove/add 我需要的数据?
(我还以为这个以前会有人问过,Stack Overflow上肯定有相关的东西,但是我没有找到合适的副本。)
问题是删除 return一个新列表;它不会修改 现有列表。 remove 的 HyperSpec 条目中的相关部分(强调已添加):
remove, remove-if, remove-if-not return a sequence of the same type as sequence that has the same elements except that those in the subsequence bounded by start and end and satisfying the test have been removed. This is a non-destructive operation. If any elements need to be removed, the result will be a copy. The result of remove may share with sequence; the result may be identical to the input sequence if no elements need to be removed.
这意味着您需要使用 return 通过 删除 编辑的值。例如,您可以 return 它,将它绑定到一个变量,或者将它分配给一个变量:
(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
请注意,该语言还包含一个 delete 函数,该函数可能具有破坏性。但是请注意,这并不能消除保存结果的需要。这意味着可以修改列表结构。不过,您仍然需要保存结果,因为旧列表中第一个的 cons 单元可能不是新列表中第一个的 cons 单元。有关更多信息,请参见,例如:
- DELETE is destructive -- but not always?
- Common Lisp: is delete-if the same as setf + remove-if?
还值得注意的是,许多 Common Lisp 函数在 序列 上运行,而不仅仅是列表。序列包括向量,字符串是向量的一个子类型。例如,(反向 "word") 将 return "drow"。同样,您可以在序列上使用 position-if。这意味着一个简单的 pig latin 函数可以像这样完成:
(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"