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

问题描述 投票:0回答:5

在 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);

导致错误“无法在可变参数之后放置所需参数

$last
”。

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

raku variadic
5个回答
6
投票
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
元素之外的所有元素。


6
投票

Perl5:

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

Perl6:

sub drop_first_last { avg( @_[ 1 .. @_.end-1 ] ) }

3
投票

使用一片。

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

1
投票

答案其余部分中显示的解决方法是正确的,但对您问题的简短回答是,Perl 6 中没有与 Python 中的

*
等效的表达式。

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

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 );

but 首先在签名中使用 slurpy

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


1
投票

如果由于其他原因需要第一个和最后一个值, 切片内未展平的列表结构映射到结果 在大多数情况下,所以你可以这样做(你必须在 $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
© www.soinside.com 2019 - 2024. All rights reserved.