Perl:%hash中的undef值 - 为什么?

时间:2014-07-06 15:01:46

标签: perl hash

下午好。我正在将一些键和值写入%hash,但我仍然得到一个我似乎无法解释的undef值。

my @maxent_unchanged = <FILE1>; 
close FILE1;
chomp (@maxent_unchanged);

my @NM;
my @max_score_unchanged;
foreach my $line(@maxent_unchanged) {

  if ($line =~ m/[a-z]/i) {
    push (@NM, $line);
  }
  else { 
    push (@max_score_unchanged, $line);
  }
}

my %max_unchanged;
my $i = 0;
foreach my $lines(@maxent_unchanged) {
  $max_unchanged{$NM[$i]} = $max_score_unchanged[$i]; ##maxent score for unchanged seq
  $i++;
}

在上下文中,@ max_unchanged在@NM和@max_score_unchanged之间交替出现如下:

$VAR1 = 'TTAAGGCAGCCCACCCGCAGGCT        >       1       110740688       110740688       C       T       GCCTGGGCGGGGAGGGCTGTCACAGTGCCGGCAGCAGCCCTTAAGGCAGC[C]CACCCGCAGGCTGCCGAGCGCTACCTGTATTTCCCCAACTGGGCCATGGC splicing  splicing        SLC6A17:NM_001010898:exon12:c.1816-10C>T';
$VAR2 = '0.77';
$VAR3 = 'TTCTATCCTTTGTTTTACAGGAA        >       1       111857154       111857154       T       C       TTAAATGGAGGGAGTCCTGACTTTTGAAGTTTATCTGTTTCTATCCTTTG[T]TTTACAGGAACAGCCAGCTGAAAACTCTCCTGGCCATTGGAGGCTGGAAC splicing  splicing        CHIA:NM_201653:exon5:c.258-8T>C';
$VAR4 = '10.99';

因此它(@maxent_unchanged)的行数是@NM和@max_score_unchanged的两倍。我已经检查了这一点,它确实存在。

如果我数据转储@NM和@max_score_unchanged我获得相同数量的变量,但是当我将这些变量放入%hash时,我得到一个额外的键值对,如数据转储哈希所示。

$VAR1 = '';
$VAR2 = undef;
$VAR3 = 'TTTTATTAATTCCTTTGTAGAAC        >       6       144835040       144835040       T       C       TATCATCTTAAATATTTCATATGGTTATGTAAGCATTTTATTAATTCCTT[T]GTAGAACCATCAGAACCAGCTAGAAATATTTGATGGGAACGTGGCTCACA splicing  splicing        UTRN:NM_007124:exon35:c.4945-5T>C';
$VAR4 = '8.22';
$VAR5 = 'TCTTTTTTGGACATGTACAGAGC        >       10      97127462        97127462        C       A       AGGAGTCTCTGAAGAAATTTCCGGAGTAGGGCTGATGGCTGAGCTCTGTA[C]ATGTCCAAAAAAGAAAAAAAAGAAGAAAAAAATAATGTAGATGATTTATT splicing  splicing        SORBS1:NM_001034957:exon13:c.1024-6G>T,NM_001034955:exon21:c.1972-6G>T,NM_001034956:exon18:c.1459-6G>T,NM_006434:exon13:c.1024-6G>T,NM_015385:exon17:c.1420-6G>T,NM_001034954:exon21:c.1906-6G>T,NM_024991:exon17:c.1147-6G>T';
$VAR6 = '4.43';

我的钥匙是独一无二的,所以我知道这不是问题。有什么想法吗?

其次,因为我想删除空的哈希键和值,我该怎么做?

非常感谢您提前耐心和帮助, ë

3 个答案:

答案 0 :(得分:2)

在此循环中,您正在迭代@maxent_unchanged,但您应该在@max_score_unchanged上进行迭代。

foreach my $lines(@max_score_unchanged) {
  $max_unchanged{$NM[$i]} = $max_score_unchanged[$i]; ##maxent score for unchanged seq
  $i++;
}

@maxent_unchanged是您将所有数据加载到的内容,因此它的行数是@NM@max_score_unchanged的两倍。

如果您use strict;use warnings,您在运行时会看到此错误:

Use of uninitialized value within @NM in hash element at test.pl line 25, <DATA> line 4.
Use of uninitialized value within @NM in hash element at test.pl line 25, <DATA> line 4.

这将指向正确的方向。您可以将print "$i\n";添加到该循环,以查看其经历的次数,并将其与@NM@max_score_unchanged的长度进行比较。

我建议您在代码中使用正确的缩进,以使其更具可读性。


实施例

use strict;
use warnings;
use Data::Dumper;

my @maxent_unchanged = <DATA>;
chomp (@maxent_unchanged);

my @NM;
my @max_score_unchanged;

foreach my $line(@maxent_unchanged) {
    if ($line =~ m/[a-z]/i) {
        push (@NM, $line);
    }
    else { 
        push (@max_score_unchanged, $line);
    }
}

my %max_unchanged;
for (my $i = 0; $i < @max_score_unchanged; $i++ ) {
    $max_unchanged{$NM[$i]} = $max_score_unchanged[$i]; ##maxent score for unchanged seq
}

print Dumper \%max_unchanged;

__DATA__
TTAAGGCAGCCCACCCGCAGGCT        >       1       110740688       110740688       C       T       GCCTGGGCGGGGAGGGCTGTCACAGTGCCGGCAGCAGCCCTTAAGGCAGC[C]CACCCGCAGGCTGCCGAGCGCTACCTGTATTTCCCCAACTGGGCCATGGC splicing  splicing        SLC6A17:NM_001010898:exon12:c.1816-10C>T
0.77
TTCTATCCTTTGTTTTACAGGAA        >       1       111857154       111857154       T       C       TTAAATGGAGGGAGTCCTGACTTTTGAAGTTTATCTGTTTCTATCCTTTG[T]TTTACAGGAACAGCCAGCTGAAAACTCTCCTGGCCATTGGAGGCTGGAAC splicing  splicing        CHIA:NM_201653:exon5:c.258-8T>C
10.99

我还举了一个示例,说明如何使用for循环上的索引进行迭代,而不是使用foreach循环,因为您不能在任何地方使用$lines


输出:

$VAR1 = {
          'TTAAGGCAGCCCACCCGCAGGCT        >       1       110740688       110740688       C       T       GCCTGGGCGGGGAGGGCTGTCACAGTGCCGGCAGCAGCCCTTAAGGCAGC[C]CACCCGCAGGCTGCCGAGCGCTACCTGTATTTCCCCAACTGGGCCATGGC splicing  splicing        SLC6A17:NM_001010898:exon12:c.1816-10C>T' => '0.77',
          'TTCTATCCTTTGTTTTACAGGAA        >       1       111857154       111857154       T       C       TTAAATGGAGGGAGTCCTGACTTTTGAAGTTTATCTGTTTCTATCCTTTG[T]TTTACAGGAACAGCCAGCTGAAAACTCTCCTGGCCATTGGAGGCTGGAAC splicing  splicing        CHIA:NM_201653:exon5:c.258-8T>C' => '10.99'
        };

答案 1 :(得分:1)

您真的需要将数据复制到多个数组中吗?是否在脚本的其他地方使用。如果没有,那么我只是在循环文件句柄时构建哈希。

use strict;
use warnings;
use Data::Dumper;

my %max_unchanged;

while (my $line = <DATA>) {
    chomp $line;
    if ($line =~ /^[ACGT]/) {
        chomp(my $value = <DATA>);
        $max_unchanged{$line} = $value;
    }
}

print Dumper \%max_unchanged;

__DATA__
TTAAGGCAGCCCACCCGCAGGCT        >       1       110740688       110740688       C       T       GCCTGGGCGGGGAGGGCTGTCACAGTGCCGGCAGCAGCCCTTAAGGCAGC[C]CACCCGCAGGCTGCCGAGCGCTACCTGTATTTCCCCAACTGGGCCATGGC splicing  splicing        SLC6A17:NM_001010898:exon12:c.1816-10C>T
0.77
TTCTATCCTTTGTTTTACAGGAA        >       1       111857154       111857154       T       C       TTAAATGGAGGGAGTCCTGACTTTTGAAGTTTATCTGTTTCTATCCTTTG[T]TTTACAGGAACAGCCAGCTGAAAACTCTCCTGGCCATTGGAGGCTGGAAC splicing  splicing        CHIA:NM_201653:exon5:c.258-8T>C
10.99

答案 2 :(得分:1)

马特正确地指出了你的问题的原因。事实上,在这种情况下迭代索引的列表会更好

my %max_unchanged;
for my $i (0 .. $#max_score_unchanged) {
  $max_unchanged{$NM[$i]} = $max_score_unchanged[$i];
}

或者您甚至可以使用map,就像这样

my %max_unchanged = map {
  $NM[$_] => $max_score_unchanged[$_];
} 0 .. $#max_score_unchanged;

但最终没有明确的理由将您的文件拆分为两个数组,您可能更喜欢这个更简洁的程序版本,它实现了相同的目的。它期望输入文件作为命令行上的参数。

use strict;
use warnings;

my %max_unchanged;
while (my $key = <>) {
  next unless $key =~ /[a-z]/;
  chomp $key;
  chomp($max_unchanged{$key} = <DATA>);
}

use Data::Dump;
dd \%max_unchanged;

根据您的示例输入数据,%max_unchanged最终看起来像这样

{
  "TTAAGGCAGCCCACCCGCAGGCT        >       1       110740688       110740688       C       T       GCCTGGGCGGGGAGGGCTGTCACAGTGCCGGCAGCAGCCCTTAAGGCAGC[C]CACCCGCAGGCTGCCGAGCGCTACCTGTATTTCCCCAACTGGGCCATGGC splicing  splicing        SLC6A17:NM_001010898:exon12:c.1816-10C>T" => 0.77,
  "TTCTATCCTTTGTTTTACAGGAA        >       1       111857154       111857154       T       C       TTAAATGGAGGGAGTCCTGACTTTTGAAGTTTATCTGTTTCTATCCTTTG[T]TTTACAGGAACAGCCAGCTGAAAACTCTCCTGGCCATTGGAGGCTGGAAC splicing  splicing        CHIA:NM_201653:exon5:c.258-8T>C"          => 10.99,
}