要点一:认识哈希
1、概念
与数组类似,哈希储存多个标量。区别如下:
- 数组用
@
符号表示,访问数组时通过下标数字访问; - 哈希用
%
符号表示。哈希通过名字(字符串)访问,联想电话簿 姓名--号码间的关系。专业术语称之为键值对。电话簿的姓名为“键”,对应的号码为键的值。
生物信息中尤其常用,比如将fasta序列的ID名与序列对应起来。注意哈希的键要保证唯一性。
2、构建哈希
- 定义一个空的哈希,也是清空哈希的一种方法
%phonenumber=(); #定义一个空的哈希,也是清空哈希的一种方法
- 法1
$phonenumber{("wang")}=123456789;
- 法2
%phonenumber=("li",12345,"zhao",789123,"chen",147852); #法2
- 法3
%phonenumber= (
"li"=>123456,
"zhao"=>789123,
"chen"=>147852,
);
-
实际构建哈希的小例子
如下图有一个文本文件,每行为省份与对应的省会,用空格分隔。这里我们将用省份作为键、省会作为值构建哈希。
#!/usr/bin/perl -w
use Data::Dumper; #加载模块,最后查看哈希数据结构用
%hash=(); #定义一个空的哈希
open IN,"<$ARGV[0]";
while (<IN>) {
chomp;
@line=split /\s+/,$_;
#以空格符分隔每行数据,储存到数组中; +为1到多个,避免有未观察到的多个空格符;
# 在本例中是将每行分隔为省份,省会两个元素储存到@line数组里。
$hash{$line[0]}=$line[1]; #变量符为$
}
close IN;
print Dumper (\%hash); #打印哈希,观察是否构建成功
3、哈希操作函数
- 取键或者值列表
@key=keys %hash; #返回哈希键列表,常用于遍历哈希
@value=values %hash; #返回哈希值列表
print "@key\n@value\n"; #无序性
@temp=sort keys %harsh
foreach (@temp)
print "$_\n";
print "$hash{$_}\n"
}
- 检测存在与否:存在为真,不存在为假
if (exists $hash{Jilin}) {
print "hash{Jilin}\n"
}
- 删除键值对
delete $hash{Jilin};
要点二:哈希实战小例子
目的:现有一个基因名文件,想从某一个序列数据库中提取所有基因名文件所包含的序列。
#!/usr/bin/perl -w
use strict;
#添加帮助信息
if (scalar @ARGV==0) { #如果输入参数个数为0
die "Usage: This program is used to get seqence by a list
perl $0 <name list> <fasta sequence>\n"; #$0表示脚本文件名
}
my %hash=();
open IN,"$ARGV[0]";
while (<IN>) {
chomp;
my @line=split /\s+/,$_;
$hash{$line[0]}=1;
#注意这里我们只利用哈希的键(基因名),值这里就随便取为1
}
close IN;
# 读入fasta文件,若基因名文件与序列ID相同,则读取;否则跳过
open FA,"<$ARGV[1]";
$/=">";<FA>; #用大于号做分隔符,分割成两段,大于号之前的空/大于号,赋值给一个空变量。
while (<FA>) {
chomp;
my $temp=(split /\n/,$_,2)[0]; #根据换行符将$_字符串分成ID与序列两个部分,数字2设置分隔的标量数
my $id=(split /\s+/,$_)[0];
if (exists $hash{$id}) { #判断ID是否存在于哈希中
print ">$_";
} else {
next;
}
}
close FA;
perl 1.pl A.list A.faa
perl 1.pl A.list A.faa | le
perl 1.pl A.list A.faa >A.unique