我有以下列表:
((a b) (c d) (e f))
要循环浏览并将列表元素组合在一起。我也有一个循环,它的工作原理与我想要的完全一样:
(loop for (x . tail) on l1
append (loop for y in tail
collect (append (list '&) x y)))
问题是,我想首先添加前两个元素,
((a b) (c d)) -> ((& a b ) (& c d) (& a b c d))
并使用此临时结果添加下一个列表,(ef)。
((a b ) (c d) (a b c d) (e f)) -> ((& a b e f) (& c d e f) (& a b c d e f))
我是否必须写一个额外的功能,该功能首先调用两个元素的LOP,还是有一种循环变量可以使用临时结果?我已经尝试使用额外的功能,但是它似乎是如此W又不自然。我真的是LISP循环的新手
I have the following list:
((a b) (c d) (e f))
and want to loop through it and combine the list elements together. I also have the loop for that, which works exactly like I want to:
(loop for (x . tail) on l1
append (loop for y in tail
collect (append (list '&) x y)))
The problem is, that I want to first add the first two elements,
((a b) (c d)) -> ((& a b ) (& c d) (& a b c d))
and use this provisional result to add the next list, (e f)
to it.
((a b ) (c d) (a b c d) (e f)) -> ((& a b e f) (& c d e f) (& a b c d e f))
Would I have to write an extra function, that calls the lop with two elements first or is there a kind of loop variable to use a provisional result? I've tried using an extra function but it just seems so wordy and unnatural. I'm really new to Lisp Loops
发布评论
评论(2)
问题陈述
OP要求模糊。给定输入列表,尚不完全清楚输出应该是什么;在问题和评论中,OP提供的示例输出中的示例输出中的不一致使这更加复杂。
OP从结合了输入列表元素的循环开始:
此循环不会产生OP预期输出中显示的那种对:
相反,上述输出是:
在
上操作的最终结果)(cd)(ef))
似乎是((& abef)(& cdef)(& abcdef))
。但这似乎缺少列表(& abcd)
。在评论中似乎是在列表上操作的结果
((ab)(cd)(ef)(gh))
应为((& ab)(& cd) (& abcd)(& abef)(& cdef)(& abcdef)(& abgh)(& cdgh)(& abcdgh)(& abefgh)(& abefgh)(& cdefgh) )
。此结果包括列表(& ab)
和(& cd)
,似乎与原始操作没有任何连接。此外,(& ef)
和(& gh)
在此结果中神秘地没有。不过,从中,OP希望收集包含第一个操作生成的所有原始组合的结果,以及在
cdr
降低的一系列列表中运行的结果,并由由加入每个列表的第一对。我可能
没有声称这是一个最佳解决方案,是一个特别好的解决方案,或者它甚至解决了OP的问题,因为它在这里不是很清楚。我只声称这可以是使用OP的原始组合操作的 a 解决方案,这很清楚。我怀疑可以通过从一开始就重新考虑问题来找到更好的解决方案。
可以将OP操作放置在函数中:
此处添加的符号
'&
被忽略;这只会在我们结合列表元素的同时混淆问题,并且完成后可以轻松地将符号预先添加到结果列表中。无需使用
combiner
在列表的前两个元素上操作,因为结果始终只是这两个列表元素的串联。编写一个通过串联前两个元素来转换列表的函数将很有用。 Singleton列表应转换为nil
:现在我们准备编写一个使用
combiner
创建所需结果的函数:操作位于
loop 宏。需要调用
删除duplicates
,因为循环的结果包含重复项,并且使用mapcar
的调用用于预处'&
结果中每个列表的符号。外循环将输入列表的较小版本逐渐馈入内部循环;这些列表中的每个列表均由
combiner
转换,然后由fancy-transform
缩小,该通过附加前两个元素或返回nil
来减少列表。当达到单身清单时(结束迭代)。将进度作为输入列表进行处理可能会有所帮助。此
花式组合插图
函数不会删除重复项或在结果中的列表中预先一个符号:lists
vss
是combiner
combiner
/code>,并且由于其中许多列表具有相同的尾巴,因此在结果中发生了重复。花式组合者
函数使用remove-duplicates
在结果中的每个列表中准备'&
符号之前,请删除这些重复。结果
这些并不是问题和评论中OP指示的结果,但是由于OP评论中似乎存在不一致之处,因此很难确切地知道预期的内容。
我必须写一个额外的功能吗?
假设该解决方案确实符合OP期望,则您可以通过使用lambda表达式代替
fancy-transform
将整个内容写入一个函数,然后将调用替换为组合
在fancy-combiner
带有等效循环表达式。这对此没有任何好处,因此所产生的代码将不清楚。OP问:“ 是否有一种循环变量使用临时结果? ,通过将
(ABCD)
插入到输入遍历期间的某个时候。这是不可能的。 被禁止破坏性地修改在traversal a traversal a thraversal 列表中操作。循环设施没有为此提供任何机制。The Problem Statement
The OP requirements are murky. Given an input list it isn't entirely clear what the output should be; this is compounded by inconsistencies in the example outputs provided by OP in the question and comments.
OP starts from a loop that combines the elements of an input list:
This loop will not produce pairs of the sort shown in OP expected output:
Instead, the output of the above is:
The final result of operating on
((a b) (c d) (e f))
appears to be((& a b e f) (& c d e f) (& a b c d e f))
. But this seems to be missing the list(& a b c d)
.In the comments is appears that the result of operating on the list
((a b) (c d) (e f) (g h))
should be((& a b) (& c d) (& a b c d) (& a b e f) (& c d e f) (& a b c d e f) (& a b g h) (& c d g h) (& a b c d g h) (& a b e f g h) (& c d e f g h) (& a b c d e f g h))
. This result includes the lists(& a b)
and(& c d)
, which don't seem to have any connection to the original operation. Further,(& e f)
and(& g h)
are mysteriously absent in this result.From this, though, it seems that the OP desires to collect a result containing all of the original combinations generated by the first operation together with the result of operating on a series of lists reduced by
cdr
and transformed by concatenating the first pair of each list.A Possible Solution
I don't claim that this is an optimal solution, a particularly good solution, or that it even solves OP's problem as it is not very clearly laid out here. I only claim that this may be a solution which uses OP's original combining operation and that is reasonably clear. I suspect that a better solution might be found by rethinking the problem from the beginning.
The OP operation can be placed in a function:
Here the added symbol
'&
is ignored; that will only confuse matters while we are combining list elements, and a symbol can easily be prepended to the result lists when we are done.There is no need to use
combiner
to operate on the first two elements of a list since the result is always just the concatenation of those two list elements. It would be useful to write a function that transforms a list by concatenating the first two elements. Singleton lists should be transformed tonil
:Now we are ready to write a function that uses
combiner
to create the desired result:The action is in the
loop
macro here. The call toremove-duplicates
is needed since the result of the loop contains duplicates, and the call tomapcar
is used to prepend'&
symbols to each list in the result.The outer loop feeds progressively smaller versions of the input list to the inner loop; each of these lists is transformed by
combiner
, then reduced byfancy-transform
, which reduces the list by appending the first two elements or returningnil
when a singleton list is reached (ending that iteration).It may help to see the progress as an input list is processed. This
fancy-combiner-illustrated
function does not remove duplicates or prepend a symbol to the lists in the result:The lists
VSS
are the ones operated on bycombiner
, and since many of these list have tails that are the same, duplicates occur in the result. Thefancy-combiner
function usesremove-duplicates
to remove these duplicates before prepending the'&
symbol to each list in the result.Results
These aren't exactly the results indicated by OP in the question and comments, but since there seem to be inconsistencies in OP comments it is hard to know exactly what is expected.
Would I Have to Write an Extra Function?
Assuming the this solution does match OP expectations, you could write the whole thing as one function by using a lambda expression in place of
fancy-transform
and replacing the call tocombiner
infancy-combiner
with the equivalent loop expression. There is no benefit to that, and the resulting code would be less clear.OP asks: "is there a kind of loop variable to use a provisional result?", but it seems that OP desires to change the input list as it is processed, e.g., by inserting
(a b c d)
into the input list at some point during the traversal of the input. This is not possible in Common Lisp; it is forbidden to destructively modify any list during a traversal operation. The loop facility does not provide any mechanism for this.我开始在没有互联网的火车上解决这个问题。
因此,当我到达时,另一个答案就在那里。
但是尽管如此,我会发布我的构造。
第一行是列表。
第二行是该列表元素的配对 - 但仅与零件
上一个元素的CDR
。第三到前排是与第二行和列表的
cdr
配对。最后一行是一切的统一。
然后我们可以做:
一个人也可以使用:
I started to solve this during a train ride where I had no internet.
So when I arrived the other answer was there.
But nevertheless, I will post my construct.
The first row is the list as it is.
The second row is pairings of the elements of this list - but only with the parts
cdr
of the last element.The third to before-last row is pairings with the second row and the
cdr
of the list.And the last row is unification of everything.
And then we can do:
One can also use: