如何在Perl列表中找到值的数量?
列表中的值数量只能通过迭代其值或将其转换为数组来确定。将其指定给标量不会返回项目计数:如何在Perl列表中找到值的数量?,perl,list,Perl,List,列表中的值数量只能通过迭代其值或将其转换为数组来确定。将其指定给标量不会返回项目计数: my $n = ('a', 'b', 'c'); # $n = 'c' 有一个“空括号”的习惯用法,可以用来获取元素的数量: my $n = () = ('a', 'b', 'c'); # $n = 3 它在内部等同于 my $n = @{[ 'a', 'b', 'c' ]}; ?为了了解阵列的大小: 使用scalar()使其显式(对于数组引用,您需要通过@{…}取消它们): 使用$#(添加一个以
my $n = ('a', 'b', 'c'); # $n = 'c'
有一个“空括号”的习惯用法,可以用来获取元素的数量:
my $n = () = ('a', 'b', 'c'); # $n = 3
它在内部等同于
my $n = @{[ 'a', 'b', 'c' ]};
?为了了解阵列的大小:
scalar()
使其显式(对于数组引用,您需要通过@{…}
取消它们):
$#
(添加一个以获得大小):
Perl:至少有两种方法:)您显示的两个项目是不等价的。但是他们有相同的最终结果
my $n = @{[ 'a', 'b', 'c' ]};
在这里,您可以创建一个匿名数组['a','b','c']
,然后取消对它的引用并计算成员数。数组的创建为语句中的逗号运算符提供了一个列表上下文
my $n = () = ('a', 'b', 'c');
这里我们使用臭名昭著的“goatse操作符”。列表
('a','b','c')
被分配给空列表()=('a','b','c')代码>。列表分配的结果被分配给$n
。列表赋值返回标量上下文中赋值右侧的项数(在列表上下文中,您将获得分配给的值列表)。否。它等效于:
my $n = (() = ('a', 'b', 'c'));
…因为赋值运算符是右关联的。右边带括号的列表赋值本身在标量上下文中,因此它的值是右边的项数。这是一个有趣的实现细节:对空列表的赋值是否会创建(不必要的)匿名数组
回答这个问题有两种方法:第一,正确的方法:尝试找出如何在源代码中处理这个问题。在标量上下文中对空列表赋值是否有特殊情况
作为懒惰和无知的类型,我选择使用:
我运行了很多次基准测试,空列表的赋值在所有情况下都有一点优势。如果差异完全是随机的,那么观察到10次计时都有利于goatse的概率小于0.1%,因此我假设存在某种短路
另一方面,当运行评论中发布的基准@daotoad时,可能会给出一个更完整的画面:
#!/usr/bin/perl
use strict; use warnings;
use Benchmark qw( cmpthese );
use constant START => 1;
use constant STOP => 1000;
my $start = START;
my $stop = STOP;
cmpthese -5, {
anon => sub { my $n = @{[ $start .. $stop ]}},
goatse => sub { my $n = () = $start .. $stop },
canon => sub { my $n = @{[ START .. STOP ]}},
cgoatse => sub { my $n = () = START .. STOP },
};
我的机器上的典型结果(Windows XP Pro SP3、Core 2 Duo、2 Gb内存、ActiveStateperl
5.10.1.1006):
结果是:
Rate anon goatse cgoatse canon
anon 1.73/s -- -12% -16% -17%
goatse 1.98/s 14% -- -4% -5%
cgoatse 2.06/s 19% 4% -- -1%
canon 2.08/s 20% 5% 1% --
速度和速度
anon 1.73/s--12%-16%-17%
goatse 1.98/s 14%--4%-5%
cgoatse 2.06/s 19%4%--1%
佳能2.08/s 20%5%1%--
结论:
如果有疑问,请使用my$n=()=代码>在标量上下文中使用时,列表的计算结果为其中的项数:
my @list = ('a', 'b', 'c');
my $list_size = @list;
进行显式测试,如在if条件下:
my @list = ('a', 'b', 'c');
if (scalar @list == 3) {
print "@list"; # prints list separated with spaces
}
如果不使用“scalar”关键字,也可以这样做。但是,这可能会使您的代码难以扫描。语境是一个好主意,但它需要读者做更多的工作。显式使用标量允许读者立即看到您正在标量上下文中计算@list
如何在中找到值的数量
Perl列表
将列表分配到@array
变量中,并使用标量(@array)
或使用操作$#array+1
获取@array
的大小。定义sub-count{scalar@}
,如果必须经常这样做,可以调用count
my $n = () = ('a', 'b', 'c'); # $n = 3
当然你可以用这个。。。如果您想让Perl继续以一个不好的名称作为只读语言…:(您还可以使用以下代码来计算数组或列表中的元素数
use strict;
use warnings;
my @array=(1,2,3,4);
my $i=0;
foreach(@array)
{
$i++;
}
print "The count is:$i\n";
仅供参考:标量上下文中没有列表:您的$n=('a','b','c'));
是逗号运算符的一个示例。请仔细阅读:特别是阅读马克·杰森·多米努斯和兰德尔·施瓦茨的回复。@martin,这是一个很好的链接。谢谢。@Ether,我觉得这些看起来不像是复制品。这个q专门针对列表。另一个是关于获取数组中已定义项的计数。-1您应该启用war然后使用qw(abc)
来理解你的愚蠢做法。列表和数组之间的区别是一件非常重要的事情。@dma_k不幸的是,你做了一件完全错误的事情,你不知道你做了什么。'$n=scalar(qw(1 2 3));
将3
赋值给$n
并不是因为列表中有三个元素,而是因为没有列表:您刚刚演示了逗号运算符。请尝试第一个示例:$n=scalar(qw(1999))这是一个愚蠢的例子,我们在有效的Perl编程中使用它来说明为什么不知道自己在做什么的人会给出错误的答案
example来说明为什么它给出了错误的答案。也就是说,核心文档明确地说这个确切的答案是错误的。另外,我在有效的Perl博客中讨论了这个问题:+1在这里留下这篇文章,作为Perl晦涩语法和Perl社区友好响应理念的证明:)感谢您的基准测试。名单的大小重要吗?另外,如果使用文本表达式定义列表,或者在执行时对其求值,这是否重要。'A'..'Z'
和1.之间有区别吗。。26
?在我的perl 5.8系统中,goatse对于短列表(10个元素)的速度大约是两倍,但是对于大列表(1000个元素),具有文字列表的anon比goatse快约30%。use constant START=>1;使用常数停止=>1000;我的$start=start;我的$stop=停止;cmpthese-5,{anon=>sub{my$n=@{[$start..$stop]},goatse=>sub{my$n=()=$start..$s
Rate anon goatse cgoatse canon
anon 1.73/s -- -12% -16% -17%
goatse 1.98/s 14% -- -4% -5%
cgoatse 2.06/s 19% 4% -- -1%
canon 2.08/s 20% 5% 1% --
my @list = ('a', 'b', 'c');
my $list_size = @list;
my @list = ('a', 'b', 'c');
if (scalar @list == 3) {
print "@list"; # prints list separated with spaces
}
my $n = () = ('a', 'b', 'c'); # $n = 3
use strict;
use warnings;
my @array=(1,2,3,4);
my $i=0;
foreach(@array)
{
$i++;
}
print "The count is:$i\n";