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

在Raku中获取懒惰Seq的最后一个元素

伏业
2023-03-14
my $s = lazy gather for ^10 { take $_ };
say $s[* - 1];
say $s.tail;
say (for $s<> { $_ }).tail;
say (for $s<> { $_ })[* - 1];

在保持原来的Seq懒惰的同时,做这件事的最惯用的方法是什么?

共有1个答案

仇经武
2023-03-14

你要问的是(“获取一个懒惰但有限的Seq的最后一个元素……同时保持原来的Seq懒惰”)是不可能的。我并不是说Raku不可能--我的意思是,原则上,任何语言都不可能像Raku那样定义“懒惰”,例如is-lazy方法。

如果是特殊的,当Seq在Raku中是惰性的时,这“意味着[Seq]的值是按需计算的,并存储起来供以后使用。”此外,惰性迭代的一个定义特性是,它在保持惰性时不能知道自己的长度--这就是为什么在惰性迭代上调用.elems会引发错误:

my $s = lazy gather for ^10 { take $_ };
say $s.is-lazy; # OUTPUT: «True»
$s.elems;       # THROWS: «Cannot .elems a lazy list onto a Seq»

现在,在这一点上,您可能会想“嗯,也许Raku不知道$s有多长,但我可以看出它里面正好有10个元素。”您没有错-使用该代码,$s确实保证有10个元素。这意味着,如果要获得$s的第十个(最后一个)元素,可以使用$s[9]。像这样访问$s的第十个元素不会改变$s.is-lazy的事实。

要了解我的意思,请考虑一个非常相似的seq

my $s2 = lazy gather for ^10 { last if rand > .95; take $_ };
say $s2.is-lazy; # OUTPUT: «True»

现在,$s2可能有10个元素,但它可能不是--唯一知道的方法是遍历它并找出答案。反过来,这意味着$S2[9]不会像$S[9]那样跳转到第十个元素;它遍历$s2,就像您需要的那样。因此,如果运行$S2[9],那么$S2将不再是惰性的(即$S2.is-lazy将返回false)。

实际上,这就是您在问题中的代码中所做的:

my $s = lazy gather for ^10 { take $_ };
say $s.is-lazy;              # OUTPUT: «True»
say (for $s<> { $_ }).tail;  # OUTPUT: «9»
say $s.is-lazy;              # OUTPUT: «False»

因为Raku永远不可能知道它已经到达惰性Seq的tail,所以它告诉您.tail的唯一方法是完全迭代$s。这必然意味着$s不再是惰性的。

值得一提的是,两个相邻的话题实际上并不相关,但它们足够接近,以至于让一些人绊倒。

首先,我没有说过惰性迭代不知道它们的长度会阻止一些非惰性迭代知道它们的长度。实际上,相当多的Raku类型同时担任迭代器角色和PredictiveIterator角色,而PredictiveIterator的要点在于,它知道可以生成多少元素,而不需要生成/迭代它们。但是predictiveIterators不能是惰性的。

我不能很好地解释这种区别,因为老实说,我自己也不完全理解它。但是我可以给出一个例子:io::handle上的。lines方法。当然,读取一个大文件的行的行为很像处理一个懒惰的迭代。最明显的是,您可以在内存中不包含整个文件的情况下处理每一行。文档甚至使用.lines方法表示“lines被懒洋洋地读取”。

另一方面:

my $l = 'some-file-with-100_000-lines.txt'.IO.lines;
say $l.is-lazy;                         # OUTPUT: «False»
say $l.iterator ~~ PredictiveIterator;  # OUTPUT: «True»
say $l.elems;                           # OUTPUT: «100000»

因此,我不太确定$L“是一个懒惰的迭代”是否公平,但如果是,它的“懒惰”方式与$S不同。

 类似资料:
  • rank ▲ ✰ vote url 61 374 45 700 url 获取列表最后一个元素 在Python里,如何获取一个列表的最后一个元素? some_list[-1]最短最Pythonic的方法. 事实上你可以用这个语法做好多事.some_list[-n]语法获取倒数第n个元素.所以some_list[-1]获取最后一个元素,some_list[-2]获取倒数第二个,等等.最后some_li

  • 问题内容: 我正在使用String split方法,并且我想拥有最后一个元素。数组的大小可以更改。 例: 我想分割上面的字符串并得到最后一个项目: 我不知道在运行时数组的大小:( 问题答案: 将数组保存在局部变量中,并使用数组的字段查找其长度。减去1以说明它是基于0的: 注意:如果原始字符串仅由分隔符组成,例如或,则为0,这将引发ArrayIndexOutOfBoundsException。示例:

  • 问题内容: 我有一个集合,我想获取集合的最后一个元素。最直接,最快捷的方法是什么? 一种解决方案是先toArray(),然后返回数组的最后一个元素。还有其他更好的方法吗? 问题答案: 这不是一个非常有效的解决方案,但是可以工作一个:

  • 问题内容: 在Python中,如何获取列表的最后一个元素? 问题答案: 是最短和最的。 实际上,你可以使用此语法做更多的事情。该语法获取第n到最后一个元素。因此获取最后一个元素,获取倒数第二个,依此类推,一直向下到,这将为你提供第一个元素。 你也可以通过这种方式设置列表元素。例如: 请注意,如果期望的项目不存在,则按索引获取列表项将引发。这意味着如果为空将引发异常,因为空列表不能有最后一个元素。

  • 本文向大家介绍js获取数组的最后一个元素,包括了js获取数组的最后一个元素的使用技巧和注意事项,需要的朋友参考一下 在js里面如何获取一个数组的最后一个元素呢?这里总结了两种方法,有需要的朋友可以看看。 (1)js内置pop方法 pop() 方法用于删除并返回数组的最后一个元素,注意这里在获取了数组的最后一个元素的同时也将原数组的最后一个元素给删除了。如果数组已经为空,则该方法不改变数组,并返回