Perl 6 中与 Python 中的星号表达式等价的是什么?

What's the equivalent in Perl 6 to star expressions in Python?

在 Python 3 中,假设你 运行 一门课程,并在学期末决定放弃第一个和最后一个家庭作业的成绩,只取其余部分的平均分他们:

def drop_first_last(grades):
    first, *middle, last = grades 
    return avg(middle)

print drop_first_last([100,68,67,66,23]);

在 Perl 6 中:

sub drop_first_last(@grades) {
    my ($first, *@middle, $last) = @grades;
    return avg(@middle);
}

say drop_first_last(100,68,67,66,23);

导致错误 "Cannot put required parameter $last after variadic parameters"。

那么,Perl 6 中与 Python 中的星号表达式等效的表达式是什么?

使用切片。

sub drop_first_last (@grades) {
    return avg(@grades[1..*-2])
}

珍珠5:

sub drop_first_last { avg( @_[ 1 .. $#_-1 ] ) }     #this
sub drop_first_last { shift;pop;avg@_ }             #or this

Pearl6:

sub drop_first_last { avg( @_[ 1 .. @_.end-1 ] ) }
sub drop_first_last(Seq() \seq, $n = 1) { seq.skip($n).head(*-$n) };
say drop_first_last( 1..10 );     # (2 3 4 5 6 7 8 9)
say drop_first_last( 1..10, 2 );  # (3 4 5 6 7 8)

工作方式:将第一个参数转换为 Seq,然后跳过 $n 个元素,然后保留除最后 $n 个元素之外的所有元素。

其余答案中显示的解决方法是正确的,但对您的问题的简短回答是 Perl 6 中没有与 Python 中的 * 等效的表达式.

这种参数通常称为可变参数,在 Perl 6 中称为 *slurpy+,因为它们 slurp rest 的参数。这就是关键,其余。在子例程签名中的 slurpy 参数之后不能声明任何参数。下面的这个例子也使用了一个解决方法:

sub avg( @grades ) {
    return ([+] @grades) / +@grades;
}

sub drop_first_last($first, *@other-grades) {
    return avg(@other-grades[0..*-1]);
}

my @grades = <10 4 8 9 10 8>;
say drop_first_last( |@grades );

但首先在签名中使用 slurpy * 来展示它是如何工作的,然后,通过使用 |@grades 调用它,是 flattening数组而不是将其绑定到数组参数中。所以长的答案是,在 Perl 6 的签名中实际上有一个 * 或可变符号,它的工作方式类似于它在 Python 中的工作方式,但它只能放在那些签名,因为它捕获了表达式的 其余 元素。

如果出于其他原因需要第一个和最后一个值, 切片内未展开的列表结构映射到结果 在大多数情况下,所以你可以这样做(你必须在 $middle 以防止自动展平):

my @grades = (1,2,3,4,5,6);
my ($first, $middle, $last) = @grades[0,(0^..^*-1),*-1];
$first.say; $middle.say; $last.say;
#1
#(2 3 4 5)
#6