【问题标题】:List of non-squares using "list comprehension" in Perl 6在 Perl 6 中使用“列表理解”的非正方形列表
【发布时间】:2019-12-02 01:46:31
【问题描述】:

如何使用 Perl 6 中的“列表理解”创建非平方列表(即平方根不是整数的整数)?我遇到了following code from Rosetta Code,它展示了如何打印非正方形列表。

sub nth_term (Int $n) { $n + round sqrt $n }

say nth_term $_ for 1 .. 22;

我对列表理解的理解是,它是一种声明方式,类似于set-builder notation,用编程语言来描述列表。

到目前为止,我注意到的最接近的事情是使用 for 关键字。但由于这实际上只是一个内联循环,我认为这不是技术上的列表理解,即使它看起来很相似:

my @y = ($_**2 + 1 for 1 .. 10);

但是,我真正想知道的是,是否有一种“列表理解”方式来创建任何数学上可描述的列表,例如非正方形。下面是我如何强制创建一个非正方形列表(最多 30 个):

my @non_squares = grep {sqrt($_) != floor(sqrt($_))}, 1 .. 30;

作为列表理解,我该如何做到这一点?

【问题讨论】:

  • 非常混乱的问题,不是很好的答案。我希望有一天能重写它们。

标签: list-comprehension raku


【解决方案1】:

实际上,您的 my @y = ($_**2 + 1 for 1 .. 10); 示例是 Perl 6 编写列表推导式的方式。您还可以按照Perl 6 design document S04 中的建议添加条件测试:

为了便于编写列表解析,允许循环语句修饰符包含单个条件语句修饰符:
...
@evens = ($_ * 2 if .odd for 0..100);

以下是如何编写非正方形(最多 30 个)的 Perl 6 列表理解:

my @non_squares = ($_ if .sqrt != .sqrt.Int for 1 .. 30);

一点解释:for 循环的每次迭代中,当前的数字在 1 到 30 的范围内被分配给默认变量 $_(又名“it”)。默认情况下,在“it”上调用没有调用者的方法调用(即.sqrt$_.sqrt 相同)。因此,对于 1 到 30 范围内的每个数字,检查其平方根以查看它是否具有非整数平方根。如果为 true,则将其包含在列表中。

【讨论】:

  • (1..30).grep: { .sqrt != .sqrt.Int } 从左到右阅读可能更清晰。 (1..30).grep: { $_ != .Int with $^n.sqrt } 可能会更快,因为它只需要为每个数字执行一次.sqrt
猜你喜欢
  • 2016-09-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-01-03
  • 1970-01-01
  • 1970-01-01
  • 2016-09-04
  • 1970-01-01
相关资源
最近更新 更多