代码之家  ›  专栏  ›  技术社区  ›  chenyf

Perl 6中的星形表达式与Python中的星形表达式有什么等价关系?

  •  6
  • chenyf  · 技术社区  · 6 年前

    在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中的星形表达式等效的表达式是什么呢?

    5 回复  |  直到 6 年前
        1
  •  6
  •   Elizabeth Mattijsen    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 元素。

        2
  •  6
  •   Kjetil S.    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
  •  3
  •   Christopher Bottoms zerkms    6 年前

    使用切片。

    sub drop_first_last (@grades) {
        return avg(@grades[1..*-2])
    }
    
        4
  •  1
  •   jjmerelo    6 年前

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

    这种参数通常称为变量,并且 *slurpy+ 在Perl 6中,因为 发出啧啧的声音 这个 休息 的参数。这是关键, 其余的 。子例程签名中的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 扁平化 数组,而不是将其绑定到数组参数中。因此,长期的答案是 * 或者Perl 6中签名中的可变符号,其工作方式类似于Python中的工作方式,但由于它捕获了 其余的 表达式的元素。

        5
  •  1
  •   Brian Julin    6 年前

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

    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