【问题标题】:Difference between a direct perl hash reference and a hash that is turned into a reference直接 perl 哈希引用和变成引用的哈希之间的区别
【发布时间】:2021-04-01 16:13:22
【问题描述】:

我试图理解此处给出的代码示例:https://www.perlmonks.org/?node_id=1083257 以及示例中给出的直接创建的哈希引用与我首先作为哈希创建的引用之间的区别。当我运行以下代码时:

use strict;
use warnings;
use Algorithm::NaiveBayes;

my $positive = {
    remit => 2,
    due => 4,
    within => 1,
};
my $negative = {
    assigned => 3,
    secured => 1,
};

my $categorizer = Algorithm::NaiveBayes->new;
$categorizer->add_instance(
    attributes => $positive,
    label => 'positive');
$categorizer->add_instance(
    attributes => $negative,
    label => 'negative');

$categorizer->train;

my $sentence1 = {
    due => 2,
    remit => 1,
};

my $probability = $categorizer->predict(attributes => $sentence1);

print "Probability positive: $probability->{'positive'}\n";
print "Probability negative: $probability->{'negative'}\n";

我得到了结果:

Probability positive: 0.999500937781821
Probability negative: 0.0315891654410057

但是,当我尝试通过以下方式创建哈希引用时:

my %sentence1 = {
    "due", 2,
    "remit", 1
};

my $probability = $categorizer->predict(attributes => \%sentence1);

我明白了:

Reference found where even-sized list expected at simple_NaiveBayes.pl line 57.
Probability positive: 0.707106781186547
Probability negative: 0.707106781186547

为什么我的哈希 \%sentence1 与示例中给出的 $sentence1 哈希引用不同?

【问题讨论】:

    标签: perl hash naivebayes


    【解决方案1】:

    就像警告所说的那样,您正在分配一个预期大小均匀的列表的引用。这个

    my %sentence1 = {   # curly bracers create a hash reference, a scalar value
        "due", 2,
        "remit", 1
    };
    

    应该是这样的

    my %sentence1 = (   # parentheses used to return a list (*)
        "due", 2,
        "remit", 1
    );
    

    (*):括号实际上并不创建列表,它们只是覆盖优先级。在这种情况下,= 超过 ,=>,这会将项目列表返回给分配。

    或者这个

    my $sentence1 = {    # scalar variable is fine for a reference
        "due", 2,
        "remit", 1
    };
    

    如果你想获得技术,在你的哈希分配中发生的事情是哈希引用{ ... }被字符串化并变成了一个哈希键。 (字符串类似于HASH(0x104a7d0))该哈希键的值将是undef,因为您分配给哈希的“列表”仅包含一件事:哈希引用。 (因此出现“偶数列表”警告)因此,如果您使用 Data::Dumper 打印这样的哈希,您会得到如下所示的内容:

    $VAR1 = {
              'HASH(0x104a7d0)' => undef
            };
    

    【讨论】:

    • Re "括号创建列表",Parens 永远不会创建列表。括号用于覆盖优先级。 (如果没有括号,则为 ( my %sentence1 = "due" ), 2。)
    • @ikegami 这在技术上是正确的,但很难简明扼要。我添加了一个解释。
    • “只需将列表直接分配给散列即可。由于不幸的运算符优先级,您将需要括号。”
    【解决方案2】:
    my %sentence1 = {
        "due", 2,
        "remit", 1
    };
    

    你做错了(你试图用一个键创建一个哈希,这是一个 hashref(它不起作用)并且没有相应的值)。这就是为什么 perl 会警告您要查找引用而不是偶数大小的列表。你想要的

    my %sentence1 = (
        "due", 2,
        "remit", 1
    );
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-06-06
      • 2015-03-23
      • 2021-09-06
      • 2011-10-11
      • 2012-06-01
      • 1970-01-01
      • 2017-01-06
      相关资源
      最近更新 更多