当前位置: 首页 > 知识库问答 >
问题:

Clojure扁平与懒惰

桓瀚
2023-03-14
(defn l-f [c]
  (if (nil? c) []
    (lazy-seq  (flatten (cons  [[ :h :j] :a :B] (l-f (rest c))))))) 


    (take 10 (l-f (repeat 2))) is how I invoke it.

这是一个相当做作的例子。另外,我知道flatten和concat将给出嵌套级别不同的序列。

我试图弄清楚为什么flatten似乎能打破这种懒惰,尽管我对Clojure.core代码的理解有限,但我认为并非如此。

共有1个答案

陶胤
2023-03-14

懒惰只是让你走了这么远--懒惰只是意味着序列在创建时没有完全实现,但是从另一个懒惰序列构建一个懒惰序列有时需要向前看几个值。在本例中,flatten的实现不能很好地与调用它的递归方式配合。

首先,flatten函数调用tree-seq对集合的内容进行深度优先遍历。反过来,tree-seq使用提供的序列调用Mapcat,该序列委托给apply,后者实现序列中的前几项,以确定要调用的函数的性质。实现序列中的前几项会导致对L-F的递归调用,该调用对其余参数调用flatten,并陷入无限循环

在这种特殊情况下,不需要递归地调用flatten,因为在第一个调用之后的任何调用都没有效果。因此,您的函数可以通过将惰性序列的生成从它的扁平化中分离出来来固定:

(defn l-f [c]                                                      
  (letfn [(l-f-seq [x] (if-let [s (seq x)]                         
                         (lazy-seq (cons [[:h :j] :a :B] (l-f-seq (rest s))))
                         []))]                                               
    (flatten (l-f-seq c))))
 类似资料:
  • 我想在指定年份之间的一年做一个季度的笛卡尔积 年度(2105、2016)应返回季度(2015、Q1)、季度(2015、Q2)...季度(2016年第四季度) 我想出的代码如下所示 上面的代码返回,我需要将其扁平化为。

  • 问题内容: 我有一个这样的清单: 此列表中的每个项目可能包含一个数据对或一个元组,我想将此列表更改为 然后这样做: 我不知道如何更改列表结构,或者如何基于原始列表进行相同的计算? 问题答案: 如果您只想整理列表,请使用:http : //docs.python.org/library/itertools.html#itertools.chain.from_iterable

  • 本文向大家介绍Python分组扁平化列表,包括了Python分组扁平化列表的使用技巧和注意事项,需要的朋友参考一下 在本教程中,我们将编写一个程序,将包含子列表的列表展开。给定的数字将子列表展开,直到给定的数字索引作为部分。让我们看一个例子来清楚地理解它。 输入项 输出结果 让我们看看解决问题的步骤。 初始化列表和编号。 初始化一个空列表。 使用范围(0,len(lists),number遍历列表

  • 我正在研究一种递归算法,将二叉树扁平化为单链表。问题陈述: 我写了下面的递归代码,它根本不起作用(返回错误的答案),但我不能从概念上理解为什么不起作用。从根开始,我们拉平根。左根和右根。如果root.left存在,那么root.next(在本例中是root.right)将指向扁平化的left列表。然后,左列表指向右列表的开始。这将沿着树递归地继续下去。 这在概念上有问题吗?我尝试在预序遍历之后对它

  • 我对递归是新手。我可以将数组展平并以普通数组的形式返回,但如果我想将数组展平并将其存储在对象中并返回值,由于某种原因,我会丢失前面结果的值,如果你能帮助我,那就太好了。PS:我可以通过每次迭代发送结果作为参数来做到这一点,但我想这样做,所以… 我甚至尝试了下面的方法,我知道我犯了一些错误,只是我找不到确切的位置 或