如果我myarray在Python中有一个数组,我可以使用切片表示法
myarray[0::2]
Run Code Online (Sandbox Code Playgroud)
仅选择偶数索引元素.例如:
>>> ar = [ "zero", "one", "two", "three", "four", "five", "six" ]
>>> ar [ 0 : : 2 ]
['zero', 'two', 'four', 'six']
Run Code Online (Sandbox Code Playgroud)
Perl中有类似的设施吗?
谢谢.
bri*_*foy 23
Perl数组切片位于@数组名称的前面,然后是您想要的索引列表:
@array[@indices];
Run Code Online (Sandbox Code Playgroud)
没有内置的语法来选择倍数,但它并不那么难.使用grep()生成所需的索引列表:
my @array = qw( zero one two three four five six );
my @evens = @array[ grep { ! ($_ % 2) } 0 .. $#array ];
Run Code Online (Sandbox Code Playgroud)
如果您使用的是PDL,那么有很多很好的切片选项.
raf*_*afl 21
有阵列切片:
my @slice = @array[1,42,23,0];
Run Code Online (Sandbox Code Playgroud)
有一种方法可以生成$ x和$ y之间的列表:
my @list = $x .. $y
Run Code Online (Sandbox Code Playgroud)
有一种方法可以从列表中构建新列表:
my @new = map { $_ * 2 } @list;
Run Code Online (Sandbox Code Playgroud)
并且有一种方法可以获得数组的长度:
my $len = $#array;
Run Code Online (Sandbox Code Playgroud)
放在一起:
my @even_indexed_elements = @array[map { $_ * 2 } 0 .. int($#array / 2)];
Run Code Online (Sandbox Code Playgroud)
当然,不如python等同,但是它做同样的工作,你当然可以把它放在一个子程序中,如果你经常使用它并希望从一些写作中省去自己.
还有一些东西可以允许以更自然的方式写出来List::AllUtils.
Eri*_*rom 11
我在CPAN上编写了模块List :: Gen,提供了另一种方法:
use List::Gen qw/by/;
my @array = qw/zero one two three four five six/;
my @slice = map {$$_[0]} by 2 => @array;
Run Code Online (Sandbox Code Playgroud)
by分区@array成两个元素的组,并返回数组引用的数组. map然后获取此列表,因此$_地图中的每个都将是一个数组引用. $$_[0](也可以写$_->[0])然后抓住by创建的每个组的第一个元素.
或者,使用内部使用的mapn功能by:
use List::Gen qw/mapn/;
my @slice = mapn {$_[0]} 2 => @array;
Run Code Online (Sandbox Code Playgroud)
或者,如果您的源列表很大并且您可能只需要某些元素,则可以使用List::Gen的是懒惰列表:
use List::Gen qw/by gen/;
my $slicer = gen {$$_[0]} by 2 => @array;
Run Code Online (Sandbox Code Playgroud)
$slicer现在是一个惰性列表(数组引用),它将根据需要生成它的切片,而不处理您没有要求的任何内容. $slicer如果你不想将它用作数组引用,也有一堆访问器方法.
我将在两个步骤中完成此操作:首先生成所需的索引,然后使用切片操作来提取它们:
@indices = map { $_ * 2 } (0 .. int($#array / 2));
my @extracted = @array[@indices];
Run Code Online (Sandbox Code Playgroud)
一步一步,多数民众赞成:
Perl 6会大大改进,但(到目前为止?)Perl 5的切片功能非常有限:你必须明确指定你想要的索引,而且它不能是开放式的.
所以你必须这样做:
@ar = ( "zero", "one", "two", "three", "four", "five", "six" );
print @ar[ grep $_ % 2 == 0, 0..$#ar ]
Run Code Online (Sandbox Code Playgroud)
使这个更美丽的一种方法是将它包装成类似的东西autobox.
例如使用autobox::Core:
use autobox::Core;
my @ar = qw/zero one two three four five six/;
# you could do this
@ar->slice_while( sub{ not $_ % 2 } );
# and this
@ar->slice_by(2);
# or even this
@ar->evens;
Run Code Online (Sandbox Code Playgroud)
这是你如何定义这些autobox方法:
sub autobox::Core::ARRAY::slice_while {
my ($self, $code) = @_;
my @array;
for (my $i = 0; $i <= $#{ $self }; $i++) {
local $_ = $i;
push @array, $self->[ $i ] if $code->();
}
return wantarray ? @array : \@array;
}
sub autobox::Core::ARRAY::slice_by {
my ($self, $by) = @_;
my @array = @$self[ map { $_ * $by } 0 .. int( $#{$self} / $by )];
return wantarray ? @array : \@array;
}
sub autobox::Core::ARRAY::evens {
my $self = shift;
my @array = $self->slice_by(2);
return wantarray ? @array : \@array;
}
Run Code Online (Sandbox Code Playgroud)
/ I3az /
| 归档时间: |
|
| 查看次数: |
3084 次 |
| 最近记录: |