关于 Perl 映射函数的建议
Posted
技术标签:
【中文标题】关于 Perl 映射函数的建议【英文标题】:Advice on Perl map function 【发布时间】:2021-07-22 14:02:45 【问题描述】:我很难理解下面 Perl 脚本中 map 函数的行为
my @list = qw/A C T G/;
my @curr = (0, undef, undef, 1);
my @res = map $list[ $_ ] @curr;
print @res; #prints AAAC
@res
的值为AAAC
。我原以为它只是AC
,因为@curr
的两个中间值是undef
。
我对map的理解是列表中的每一项依次变成$_
的值。所以我可以理解$list[0]
如何返回A 以及$list[1]
如何返回C。我不明白undef
值为什么/如何返回A?在我看来$list[undef]
不会是一个值?
我可能在这里遗漏了一些明显的东西,但非常感谢您的帮助
我从中获取此代码的脚本如下。我在调试器中单步执行它,我可以在sub gen_permutate
返回的最后一行看到这种行为
my @DNA = qw/A C T G/;
my $seq = gen_permutate(14, @DNA);
while ( my $strand = $seq->() )
print "$strand\n";
sub gen_permutate
my ($max, @list) = @_;
my @curr;
return sub
if ( (join '', map $list[ $_ ] @curr) eq $list[ -1 ] x @curr )
@curr = (0) x (@curr + 1);
else
my $pos = @curr;
while ( --$pos > -1 )
++$curr[ $pos ], last if $curr[ $pos ] < $#list;
$curr[ $pos ] = 0;
return undef if @curr > $max;
return join '', map $list[ $_ ] @curr;
;
J
【问题讨论】:
始终使用use strict; use warnings;
或同等名称。它会揭示你为什么得到AAAC
。
【参考方案1】:
这是“DWIM”的一部分——数组索引需要是一个数字,所以传入的内容被转换为一个,尽可能解释器可以做/猜测。在undef
的情况下,至少很清楚——变成0
。
但这确实是一个编程错误,或者至少是草率。
做你想做的事:
my @res = map $list[ $_ ] grep defined @curr;
或者,在列表的一次迭代中
my @res = map defined $_ ? $list[$_] : () @curr;
这里由()
表示的空列表被展平到返回列表中,因此消失了;所以我们也在map
内部过滤。但是这个三元组的重点是能够放一些有意义的东西,如果需要删除一些输入,那么首先有一个明确的grep
会更清楚。
注意 使用use warnings;
,您会听到所有相关信息
在...的数组元素中使用未初始化的值 $_
(它会将其转换为数字)
每个脚本确实必须以use warnings;
(和use strict;
)开头。有时,继承旧脚本的最重要部分是立即将use warnings;
粘贴在顶部(并通过全屏消息工作:(。
【讨论】:
【参考方案2】:我想回答我自己的问题,undef 有时被视为零。这就是为什么 $list[undef] 与 $list[0]
相同的原因【讨论】:
undef 是一个有效的标量,一个在数值操作/上下文中为 undef 的变量,它假装为 0,而在字符串操作/上下文中,它假装为空字符串。正如@zdim 提到的如果启用警告,程序将警告消息 更简单地说,当您将 undef 视为数字时,您会收到警告(如果启用)并且使用 0(而不是杀死您的程序)。以上是关于关于 Perl 映射函数的建议的主要内容,如果未能解决你的问题,请参考以下文章