【问题标题】:Advice on Perl map function关于 Perl 映射函数的建议
【发布时间】: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

标签: perl dictionary


【解决方案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(而不是杀死您的程序)。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-01-26
    • 2019-09-19
    • 2019-09-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-07-01
    相关资源
    最近更新 更多