如何将每个数组成员乘以perl中的标量?

时间:2011-04-15 00:06:53

标签: arrays perl scalar

这是代码......

use strict;
use warnings;

my @array= (1,2,3,4,5);
my $scalar= 5;

@array= $scalar*@array;

print @array;

需要能够用很少的代码执行类似功能的东西。谢谢!

6 个答案:

答案 0 :(得分:10)

使用foreach。

foreach my $x (@array) { $x = $x * $scalar; }

答案 1 :(得分:9)

你可以试试这个:

@array = map { $_ * $scalar } @array;

或更简单:

map { $_ *= $scalar } @array;

答案 2 :(得分:7)

如何:

foreach(@array)
{ $_ *= $scalar }

如您所见,您可以在遍历时就地修改数组。

答案 3 :(得分:5)

我不知道你需要的范围。 IFF你正在进行数值数据操作,Perl数据语言(PDL)获取一组数值数据,从中创建一个“小提琴”对象,并重载数学运算以“向量化”它们的操作。这是一个非常有效的数字处理系统。无论如何这里是一个例子:

#!/usr/bin/perl

use strict;
use warnings;

use PDL;

my $pdl_array = pdl([1,1,2,3,5,8]);
print 2*$pdl_array;

__END__
gives:
[2 2 4 6 10 16]

答案 4 :(得分:4)

此评论适用于SoloBold。

以下是对map方法的测试:

#!/usr/bin/perl                                                                                                                                                                                                          

use strict;
use warnings;
use Benchmark;

my @array = ();
push(@array, (1) x 1000000);
my $scalar = 5;

my $startTime = new Benchmark();

@array = map { $_ * $scalar } @array;

my $stopTime = new Benchmark();

print STDOUT "runtime: ".timestr(timediff($stopTime, $startTime), 'all')." sec\n";

以下是对foreach方法的测试:

#!/usr/bin/perl                                                                                                                                                                                                          

use strict;
use warnings;
use Benchmark;

my @array = ();
push(@array, (1) x 1000000);
my $scalar = 5;

my $startTime = new Benchmark();

foreach my $x (@array) { $x = $x * $scalar; }

my $stopTime = new Benchmark();

print STDOUT "runtime: ".timestr(timediff($stopTime, $startTime), 'all')." sec\n";

这是我正在运行的系统:

bash-3.2$ perl --version
This is perl, v5.8.8 built for darwin-2level
...
bash-3.2$ uname -a
Darwin Sounder.local 10.7.0 Darwin Kernel Version 10.7.0: Sat Jan 29 15:17:16 PST 2011; root:xnu-1504.9.37~1/RELEASE_I386 i386

以下是一项测试的结果:

bash-3.2$ ./test.map.pl
runtime:  4 wallclock secs ( 0.41 usr  0.70 sys +  0.00 cusr  0.00 csys =  1.11 CPU) sec
bash-3.2$ ./test.foreach.pl
runtime:  0 wallclock secs ( 0.13 usr  0.00 sys +  0.00 cusr  0.00 csys =  0.13 CPU) sec

这些时间在同一台机器上相当可重复,并且在双核Linux机器上的结果有些可重复:

[areynolds@fiddlehead ~]$ perl --version
This is perl, v5.8.8 built for x86_64-linux-thread-multi
...
[areynolds@fiddlehead ~]$ uname -a
Linux fiddlehead.example.com 2.6.18-194.17.1.el5 #1 SMP Mon Sep 20 07:12:06 EDT 2010 x86_64 GNU/Linux
[areynolds@fiddlehead ~]$ ./test.map.pl
runtime:  0 wallclock secs ( 0.28 usr  0.05 sys +  0.00 cusr  0.00 csys =  0.33 CPU) sec
[areynolds@fiddlehead ~]$ ./test.foreach.pl
runtime:  0 wallclock secs ( 0.09 usr  0.00 sys +  0.00 cusr  0.00 csys =  0.09 CPU) sec

对于mapforeach,OS X框上的性能比率要慢8.53倍。在Linux机器上,同样慢3.67倍。

我的Linux机箱是双核的,内核比我的单核OS X笔记本电脑略快。

修改

我在我的OS X盒子上将Perl从v5.8.8更新到v5.12.3并且速度相当快,但是map仍然比foreach更糟糕:

sounder:~ alexreynolds$ perl --version
This is perl 5, version 12, subversion 3 (v5.12.3) built for darwin-multi-2level
...
sounder:~ alexreynolds$ ./test.map.pl
runtime:  0 wallclock secs ( 0.45 usr  0.08 sys +  0.00 cusr  0.00 csys =  0.53 CPU) sec
sounder:~ alexreynolds$ ./test.foreach.pl
runtime:  1 wallclock secs ( 0.18 usr  0.00 sys +  0.00 cusr  0.00 csys =  0.18 CPU) sec

这从8.53倍恶化到2.94倍恶化。相当可观的改进。

Linux盒子稍微执行了更糟,并将其Perl安装升级到v5.12.2:

[areynolds@basquiat bin]$ perl --version    
This is perl 5, version 12, subversion 2 (v5.12.2) built for x86_64-linux-thread-multi
...
[areynolds@basquiat bin]$ /home/areynolds/test.map.pl
runtime:  1 wallclock secs ( 0.29 usr  0.07 sys +  0.00 cusr  0.00 csys =  0.36 CPU) sec
[areynolds@basquiat bin]$ /home/areynolds/test.foreach.pl
runtime:  0 wallclock secs ( 0.08 usr  0.00 sys +  0.00 cusr  0.00 csys =  0.08 CPU) sec

这从3.67倍恶化到4.5倍恶化 - 不太好!升级可能并不总是值得的,只是为了它的升级。

答案 5 :(得分:0)

对我来说不幸的是,拉里不允许这样做

GET http://localhost:51249/Course/Index/~/Images/Course/html.jpg 404 (Not Found)

$scalar *operator* (list) 

当然可以使用map或loops,但是语法与上面一样清晰得多。

(list) *operator* $scalar

如果2个长度相等也很有意义。

惊讶的拉里不允许这样做,只是说..我想在这种情况下,有(n-1)种方法可以做到。

 (list) *operator* (list) 

甚至

my @a = 'n' . (1..5);
my @a = 2 * (1..5);