Emacs列表不是一个列表
此代码的计算结果为Emacs列表不是一个列表,emacs,elisp,Emacs,Elisp,此代码的计算结果为t (listp '(foo 0 . 0)) 这些代码给出了一个错误:eval:error-type参数:listp,0 (mapcar (lambda (x) x) '(foo 0 . 0)) (length '(foo 0 . 0)) 所有三个都使用相同的“列表”,但mapcar和length显然不认为它是一个列表。这是因为列表以0结尾。0而不是0,尽管我不知道为什么这对mapcar有影响,但对listp没有影响 有没有一种方法可以修改mapcar表达式以接受常规列表,
t
(listp '(foo 0 . 0))
这些代码给出了一个错误:eval:error-type参数:listp,0
(mapcar (lambda (x) x) '(foo 0 . 0))
(length '(foo 0 . 0))
所有三个都使用相同的“列表”,但mapcar
和length
显然不认为它是一个列表。这是因为列表以0结尾。0
而不是0
,尽管我不知道为什么这对mapcar
有影响,但对listp
没有影响
有没有一种方法可以修改mapcar表达式以接受常规列表,如(foo 0)
,以及这些cons样式列表(foo 0.0)
?在实际的应用程序中,我的输入有两种类型的列表(例如,(“a”(b0.0)(c0.0))
,lambda是一个递归函数,如果其参数是列表,则调用mapcar
(如果上一段不清楚,则回答“改用(foo 0)
”是错误的。)
我怀疑答案是这样的
(defun my-func (x)
(if (consp x)
(if (not-actually-a-list-p x)
(delistify (mapcar #'myfunc (listify x)))
(mapcar #'myfunc input))
; process the individual atoms
))
但是,我不知道
not-actual-a-list-p
、listify
和delitify
应该是什么。listp
对于cons单元格返回非nil
:
listp is a built-in function in ‘C source code’.
(listp OBJECT)
Return t if OBJECT is a list, that is, a cons cell or nil.
Otherwise, return nil.
listp
不检查真实列表(即,最后一个单元格的cdr为nil
)
mapcar
和length
要求列表参数为真列表
要将mapcar
应用于可能不是正确列表的列表,可以执行以下操作:
(取消我的地图(fn conses)
“类似于‘地图车’,但也适用于虚线列表。”
(let((res()))
(而(消费)
(推动(功能所有fn(车辆消耗))res)
(setq conses(cdr conses)))
(当消耗(推送(所有fn消耗)恢复时)
(nreverse res)))
listp
返回cons单元格的非nil
:
listp is a built-in function in ‘C source code’.
(listp OBJECT)
Return t if OBJECT is a list, that is, a cons cell or nil.
Otherwise, return nil.
listp
不检查真实列表(即,最后一个单元格的cdr为nil
)
mapcar
和length
要求列表参数为真列表
要将mapcar
应用于可能不是正确列表的列表,可以执行以下操作:
(取消我的地图(fn conses)
“类似于‘地图车’,但也适用于虚线列表。”
(let((res()))
(而(消费)
(推动(功能所有fn(车辆消耗))res)
(setq conses(cdr conses)))
(当消耗(推送(所有fn消耗)恢复时)
(nreverse res)))
之所以listp
返回T
是因为它只检查参数是nil
还是cons单元格。正确的列表要么是nil
,要么是所有cdr
都满足listp
的列表
mapcar
和length
实际上必须迭代列表并阻塞不正确的列表,因为它们无法获取非cons单元格的内容的cdr
您只需实现mapcar dot
即可解决问题。例如,下面是一种递归方法:
(定义地图车点(f列表)
(字体列表)
(零)
(反对者(反对者)(汽车清单)
(地图车点f(cdr列表)))
(t(funcall f list)))
范例
(列表(地图车点#'1+'(1234))
(地图车点#'1+'(123.4)))
=> ((2 3 4 5) (2 3 4 . 5))
在这里,我保留了原始结构,这意味着作为输入的不正确列表将作为输出的不正确列表。我不知道这是否是您想要的。如果您希望始终返回正确列表,那么只需执行以下操作:
(定义地图车点*(f列表)
(循环用于列表中的(a.b)
收集(全部f a)
除非(列表b)
收集(全部f b)))
之所以listp
返回T
是因为它只检查参数是nil
还是cons单元格。正确的列表要么是nil
,要么是所有cdr
都满足listp
的列表
mapcar
和length
实际上必须迭代列表并阻塞不正确的列表,因为它们无法获取非cons单元格的内容的cdr
您只需实现mapcar dot
即可解决问题。例如,下面是一种递归方法:
(定义地图车点(f列表)
(字体列表)
(零)
(反对者(反对者)(汽车清单)
(地图车点f(cdr列表)))
(t(funcall f list)))
范例
(列表(地图车点#'1+'(1234))
(地图车点#'1+'(123.4)))
=> ((2 3 4 5) (2 3 4 . 5))
在这里,我保留了原始结构,这意味着作为输入的不正确列表将作为输出的不正确列表。我不知道这是否是您想要的。如果您希望始终返回正确列表,那么只需执行以下操作:
(定义地图车点*(f列表)
(循环用于列表中的(a.b)
收集(全部f a)
除非(列表b)
收集(全部f b)))
我真的很想说“使用(foo 0 0)来代替”,但你肯定有你的理由:-)@coredump我的输入是c风格的。这不是我能控制的。(如果它在我的控制之下,我会改变它,而不是试图搜索问题并修补它。)我真的很想说“改用(foo 0 0)”,但你肯定有你的理由:-@coredump我的输入是c-style-alist`。这不是我能控制的。(如果它在我的控制之下,我会改变它,而不是试图搜索问题并修补它。)这就是我所需要的(包括维护不正确的结构)。(a.b)vs.(a.b)总是让我感到困惑。(1.2)
是一个cons单元,其中1个在其汽车中,2个在其cdr中。它可能是用(cons 1 2)
创建的。另一方面,(12)
是两个cons单元。第一个单元的车内有1个单元,其cdr指向第二个单元,第二个单元的车内有2个单元,其cdr中有nil
。可能吧