【问题标题】:how to assign a value to a hash in perlperl中如何给哈希赋值
【发布时间】:2017-10-28 01:14:38
【问题描述】:

这是工作的一部分。在这一部分中,我正在尝试编写一个程序来创建哈希。键是文件中的登录号,值是整行。但是,该程序给了我一个警告。代码是:

#!/usr/bin/perl

#psuedocode:
#open file1, store uniport accesion as key and the line as value
#open file2, store uniport accesion as key and the line as value which lines contain "IDA"
#compare keys in two hashes, find out matched keys
#print out lines from file2 that match

use strict;
use warnings;
use feature qw(say);

my $infile1 = "geneIDs3_MouseToUniProtAccessions.txt";
my $inFH1;
open ($inFH1, "<", $infile1) or die join (" ", "Can't open", $infile1, "for reading:", $!);
my @array1 = <$inFH1>;
close $inFH1;
shift @array1;
my %geneID1;
for ($a = 0; $a < scalar @array1; $a++){
    chomp $array1[$a];
    $array1[$a] =~ /.*?\t(.*?)\t.*/;
    $geneID1{$1} = $array1[$a];
    #say ("$1", '->', "$geneID1{$array1[$a]}");    #test if the hash has been successfully created, however it doesn't
    #say $array1[$a];              #test if the program can recognize the elements, it does
}

文件geneIDs3_MouseToUniProtAccessions.txt 包含1,000 行,因此警告很多。前两行是:

From    To  Species Gene Name
PNMA3   Q9H0A4  Homo sapiens    paraneoplastic antigen MA3

警告如下:

Use of uninitialized value within %geneID1 in string at match_for_part_III_10.pl line 24.
Q9H0A4->

我找到了解决方案:改用 while 循环。它不仅有效,而且更优雅。新代码是:

 #!/usr/bin/perl

#psuedocode:
#open file1, store uniport accesion as key and the line as value
#open file2, store uniport accesion as key and the line as value which lines contain "IDA"
#compare keys in two hashes, find out matched keys
#print out lines from file2 that match

use strict;
use warnings;
use feature qw(say);

my $infile1 = "geneIDs3_MouseToUniProtAccessions.txt";
my $inFH1;
open ($inFH1, "<", $infile1) or die join (" ", "Can't open", $infile1, "for reading:", $!);
my %geneID1;

while (<$inFH1>){
    $_ =~ /.*?\t(.*?)\t.*/;
    $geneID1{$1} = $_;
    say ("$1", '->', "$geneID1{$1}");
}
close $inFH1;

感谢大家的大力帮助!

【问题讨论】:

  • 警告=您没有处理某些情况,可能缺少数据。你为什么不把它们打印出来看看。
  • @zdim 其他部分工作得很好。我不需要声明$a,请阅读我上一个问题stackoverflow.com/questions/46739301/…的评论
  • @zdim, $a 总是被声明。
  • @Wenjia Zhai,你知道$a很特别,你还用吗?坏你!
  • Re "我找到了解决方案:改用 while 循环",不,这并没有解决问题,而 没有“找到”它的那个。如上所述,问题在于您使用了错误的密钥。 (你分配给$geneID1{$1},但是你查看$geneID1{$array1[$a]}的内容)

标签: perl


【解决方案1】:
#!/usr/bin/perl

use strict;
use warnings;
use feature qw( say );

<>; # Skip header.

my %geneID1;
while (<>) {
   chomp;
   my @fields = split /\t/;
   my $id = $fields[1];
   $geneID1{$id} = $_;
}

say "$_ => $geneID1{$_}" for sort keys %geneID1;

(将geneIDs3_MouseToUniProtAccessions.txt 作为参数传递。)

【讨论】:

  • 感谢您的建议。在我尝试了while循环之后,它确实有效。我已将新代码放在我原来的帖子中
  • 很遗憾重新添加了我删除的错误?!? $1 是垃圾,除非您确保匹配成功,并且您的正则表达式是一种可读性差且速度慢的标签拆分方式。不幸的是,您恢复为不灵活的界面,而不是接受文件名作为参数。
  • @yacc,你错了。失败的匹配不会改变$1,正如您通过运行以下命令所看到的那样:perl -Mfeature=say -e'for (qw( abc def )) { /(b)/; say $1 // "[undef]"; }' /// 此外,失败的匹配设置$1undef 实际上是一件好事,而我的程序确实如此完全相同的东西(如果没有标签,则将 $id 设置为 undef)。
  • 你是对的,我错了。也许我是从早期的 Perl 版本中得到的。 @ikegami
【解决方案2】:

很难用标签(它们是标签吗?)和更改问题中的代码来判断错误是什么。

但是,代码中有很多元素可以改进

use warnings;
use strict;
use feature 'say';

my $file = 'geneIDs3_MouseToUniProtAccessions.txt';
open my $fh, '<', $file or die "Can't open $file: $!";

my %geneID1;

my $header = <$fh>;    
while (<$fh>) {
    chomp;
    $geneID1{ (split /\t/)[1] } = $_; 
}

say "$_ => $geneID1{$_}" for sort keys %geneID1;

唯一的“通配符”是您的数据;如果您不确定TAB 字符,请使用\s+(也匹配制表符),因为您只需要第二个字段。通过split 默认值,您可以执行(split)[1]

对原代码的注释

  • 只有在有非常具体的原因时才提前读取文件

  • 声明所有内容,即使某些特殊功能允许您不声明 ($a)

  • 在尽可能小的范围内声明并靠近需要的地方:open my $fh, ...

  • 不要使用像 $a 这样的特殊变量,除非它们的用途不同!

  • 几乎不需要 C 风格的 for 循环。如果您在迭代中需要索引

    foreach my $i (0 .. $#ary) { ... }
    

    其中$#ary是数组@ary的最后一个元素的索引

【讨论】:

  • 感谢您的建议。为了便于阅读,我提前声明了$inFH1。这只是我的风格。我不知道什么是C风格,我只是学编程,我想尽可能的清楚。
  • @WenjiaZhai (1) 使用open 实际上没有作用域优势,但通常最好在需要的地方声明正确。当它在open 下被声明时,永远不会混淆它的所属位置。 (2) “C 风格”循环通常指的是for (my $i = 0, $i &lt; SIZE; ++$i)——就像你在 C 中做循环一样。Perl 是一种高级得多的语言,并提供了其他更方便的方法。
  • @WenjiaZhai 继续学习,享受吧:)。找到你的风格(但也要注意“良好做法”)
  • 提前声明变量的一个主要原因是,即使在使用my 之后,我通常也会反击错误Global symbol requires explicit package name。找不到原因,但是发现如果早点声明变量就不会出现这个错误了。
  • 感谢您的鼓励!我在编程时确实很开心。我也从这个论坛学到了很多东西。
猜你喜欢
  • 1970-01-01
  • 2010-10-20
  • 1970-01-01
  • 1970-01-01
  • 2023-04-07
  • 2013-08-26
  • 1970-01-01
  • 2021-12-30
  • 2014-04-13
相关资源
最近更新 更多