Что в Perl 6 эквивалентно выражению в виде звезды в Python? - PullRequest
0 голосов
/ 03 мая 2018

В 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 ]

0 голосов
/ 09 мая 2018

Если первое и последнее значения необходимы по какой-либо другой причине, неразбросанная структура списка внутри срезов отображается в зависимости от результатов в большинстве случаев, так что вы можете сделать это (вы должны использовать $ 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
0 голосов
/ 04 мая 2018

Временные решения, такие как показанные в остальной части ответа, верны, но краткий ответ на ваш вопрос состоит в том, что в Perl 6 нет эквивалентного выражения в * в Python.

Этот тип аргументов называется, как правило, переменным и * slurpy + в Perl 6, потому что они slurp остальные аргументов. И это ключ, остальное . Не может быть аргумента, объявленного после неаккуратного аргумента в подписи подпрограммы. В этом примере ниже также используется обходной путь:

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, но его можно поставить только последним в этих сигнатурах, поскольку он захватывает * 1020. * остальные элементов выражения.

0 голосов
/ 03 мая 2018

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 ] ) }
0 голосов
/ 03 мая 2018
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 элементов.

0 голосов
/ 03 мая 2018

Использовать ломтик.

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