商城首页欢迎来到中国正版软件门户

您的位置: 首页 > 文章列表 > 编程开发 > Perl中的列表和数组学习笔记

Perl中的列表和数组学习笔记

  发布于2026-06-29 阅读(0)

扫一扫,手机访问

Perl 中的列表与数组,可以说是这门语言最基础也最灵活的数据结构之一。很多初学者一开始会被它们看似相近的概念搞混,但实际上,理解清楚这两者的区别与用法,后面的编程就会顺畅得多。下面我们一步步把它们拆开来看。

一、列表

Perl中的列表和数组学习笔记

列表就是放在圆括号里的一串值,可以是数字、字符串,甚至什么也没有——空列表 ()。比如 (1, 5.3, "hello", 2) 就是一个典型的列表。有一点要注意:单独一个数值的列表(比如 (43.2))和这个数值本身(43.2)在类型上并不相同,但 Perl 会在需要的时候自动进行转换。来看几个例子:

复制代码 代码如下:

(17, $var, "a string")
(17, 26 << 2)
(17, $var1 + $var2)
($value, "The answer is $value")

二、数组——列表的存贮

列表本身只是一串数据,而数组则是用来存放这些数据的变量。数组变量以 @ 开头,比如:

复制代码 代码如下:

@array = (1, 2, 3);

几个需要记住的点:

  • 数组刚创建时,默认是空列表 ()
  • 因为 Perl 用 @$ 来区分数组变量和普通标量,所以同一个名字可以同时用于数组和标量(比如 $var@var 可以共存),但这样做很容易让人糊涂,所以不推荐这么干。

1、数组的存取

数组元素用下标访问,第一个元素下标是 0。访问不存在的元素会得到 undef,但如果你给一个超出当前长度的下标赋值,数组会自动增长,中间空缺的位置自动补上 undef。看看下面这段:

复制代码 代码如下:

@array = (1, 2, 3, 4);
$scalar = $array[0];
$array[3] = 5; # now @array is (1,2,3,5)
$scalar = $array[4]; # now $scalar = null;
$array[6] = 17; # now @array is (1,2,3,5,"","",17)

数组之间可以直接拷贝:

复制代码 代码如下:

@result = @original;

也可以用数组给列表赋值:

复制代码 代码如下:

@list1 = (2, 3, 4);
@list2 = (1, @list1, 5); # @list2 = (1, 2, 3, 4, 5)

数组还可以给标量变量赋值——注意这种赋值是按列表匹配的:

  • @array = (5, 7, 11); ($var1, $var2) = @array; 结果 $var1=5, $var2=7,剩下的 11 被忽略。
  • 反过来,如果数组元素不够,多余的标量会得到 undef
复制代码 代码如下:

($var1, $var2) = @array; # $var1 = 5, $var2 = 7, 11被忽略

从标准输入读取也很方便:

复制代码 代码如下:

$var = ;
@array = ; # ^D为结束输入的符号

2、字符串中的方括号和变量替换

在双引号字符串中,"$var[0]" 会被解释为数组 @var 的第一个元素。如果你不想这样,可以用反斜线转义:"$var[0]" 等价于 "$var" . "[0]"。另外 "${var}[0]""$var[0]" 效果相同。而 "${var}" 则把花括号当成普通字符,不会做变量替换。

复制代码 代码如下:

"$var[0]" 为数组@var的第一个元素。
"$var[0]" 将字符"["转义,等价于"$var". "[0]",$var被变量替换,[0]保持不变。
"${var}[0]" 亦等价于"$var" ."[0]"。
"${var}"则取消了大括号的变量替换功能,包含文字:${var}.

3、列表范围

.. 运算符可以便捷地生成连续数值或字符串的列表:

复制代码 代码如下:

(1..10) = (1, 2, 3, 4, 5, 6, 7, 8, 9, 10)
(2, 5..7, 11) = (2, 5, 6, 7, 11)
(3..3) = (3)

对于实数,.. 按步长 1 递增:(2.1..5.3) 得到 (2.1, 3.1, 4.1, 5.1)。如果起始值大于结束值,返回空列表。

对于字符串,.. 按照 ASCII 顺序自动递增,比如 ("aaa".."aad") 得到 ("aaa","aab","aac","aad")。甚至可以用它来生成日期的字符串:@day_of_month = ("01".."31")

范围中还可以包含变量或表达式,比如 ($var1..$var2+5)。一个小技巧:利用 x 操作符重复字符串:

复制代码 代码如下:

$fred = "Fred";
print (("Hello, " . $fred . "!\n") x 2);

结果会输出两行 "Hello, Fred!"。

4、数组的输出

将数组直接放在 print 中,元素会被紧密拼接在一起:

复制代码 代码如下:

print (@array, "\n"); # 输出 123

但如果把数组放在双引号里,元素之间会自动用空格分隔:

复制代码 代码如下:

print ("@array\n"); # 输出 1 2 3

5、列表/数组的长度

当数组出现在期待标量的上下文时,Perl 会自动取其长度:

复制代码 代码如下:

@array = (1, 2, 3);
$scalar = @array; # $scalar = 3, 即@array的长度
($scalar) = @array; # $scalar = 1, 即@array第一个元素的值

利用这个特性可以很方便地控制循环次数:

复制代码 代码如下:

$count = 1;
while ($count <= @array) {
print ("element $count: $array[$count-1]\n");
$count++;
}

6、子数组

你可以用多个下标或范围来截取数组的一部分:

复制代码 代码如下:

@array = (1, 2, 3, 4, 5);
@subarray = @array[0,1]; # @subarray = (1, 2)
@subarray2 = @array[1..3]; # @subarray2 = (2,3,4)
@array[0,1] = ("string", 46); # @array =("string",46,3,4,5) now
@array[0..3] = (11, 22, 33, 44); # @array = (11,22,33,44,5) now
@array[1,2,3] = @array[3,2,4]; # @array = (11,44,33,5,5) now
@array[0..2] = @array[3,4]; # @array = (5,5,"",5,5) now

利用子数组还可以轻松交换两个元素的位置:

复制代码 代码如下:

@array[1,2] = @array[2,1];

7、有关数组的库函数

Perl 提供了一些非常实用的数组处理函数,下面列出最常用的几个。

sort —— 按字符顺序排序:

复制代码 代码如下:

@array = ("this", "is", "a","test");
@array2 = sort(@array); # @array2 = ("a","is", "test", "this")
@array = (70, 100, 8);
@array = sort(@array); # @array = (100, 70, 8) now

reverse —— 反转数组:

复制代码 代码如下:

@array2 = reverse(@array);
@array2 = reverse sort (@array);

chop —— 去掉每个元素末尾的字符(通常用于去掉换行符):

复制代码 代码如下:

@list = ("rabbit", "12345","quartz");
chop (@list); # @list = ("rabbi", "1234","quart") now

join/split —— 连接与拆分:

复制代码 代码如下:

$string = join(" ", "this", "is","a", "string"); # 结果为"this is a string"
@list = ("words","and");
$string = join("::", @list, "colons"); #结果为"words::and::colons"
@array = split(/::/,$string); # @array = ("words","and", "colons") now

如果把标量比作 Perl 中的单数,那么列表和数组就是复数。列表是标量的有序集合,而数组则是用来存放列表的变量。虽然在实际使用中这两个术语经常被混用,但严格来说,列表指的是数据本身,数组是存放数据的变量名。你可以有一串值(列表)而不属于任何数组;但每一个数组变量都对应一个列表,哪怕它是空的。

列表中的每个元素都是独立的标量值,它们按顺序排列,从索引 0 开始递增。一个列表或数组可以包含数字、字符串、undef 甚至不同类型混合在一起。当然,实际编程中建议保持类型一致,这样代码更容易理解。

列表和数组的长度没有硬性限制——最少 0 个元素,最多可以填满你的可用内存。这正体现了 Perl 的设计哲学:“不必要的限制一律不要”。

1. 访问数组元素

通过索引访问元素非常直观:$array[0] = "test"; print $array[0];。注意数组名和标量名属于不同的命名空间,所以你可以同时拥有 $array@array,但不要这么做,容易混淆。

2. 特殊的数组索引

如果你给数组最后一个元素后面的位置赋值,数组会自动扩展。Perl 不会限制你的长度,只要你内存够用。自动扩展时,中间缺失的元素会被赋值为 undef

获取数组最后一个元素的索引可以用 $#array。另外 Perl 还支持负数索引:-1 表示最后一个元素,-2 表示倒数第二个,依此类推。不过实际中大多数人只用 -1

3. 列表

列表就是用圆括号括起来、逗号分隔的一系列值。这些值不一定是常数,也可以是表达式,在运行时才计算。

4. qw 简写

字符串列表在 Perl 中太常用了,所以有了 qw 这个便捷写法。它把空白分隔的单词当成单引号字符串处理,省去大量输入引号的麻烦。注意 qw 内部不能使用变量替换和转义字符 \n,而且不能用注释。Perl 允许任何标点符号作为分隔符,比如 qw/ ... /qw{ ... } 等。

5. 列表赋值

你可以像给标量赋值一样,把列表赋给一组变量:

复制代码 代码如下:

($fred[0], $fred[1], $fred[2]) = ("haha", "wawa", undef);
print $fred[0].$fred[1].$fred[2];

左边的每个变量都会得到对应的值,这相当于连续执行三个赋值语句。甚至可以用它来交换两个变量的值——因为列表是在赋值之前就已经构建好了。另外,如果你想引用整个数组,只需在数组名前加 @(不带中括号)。

6. pop 和 push 操作

pop 从数组末尾取出并返回最后一个元素:

复制代码 代码如下:

@array = 5..9;
pop @array;
foreach $t (@array) {
print $t;
}

push 则相反,把一个或多个元素追加到数组末尾:

复制代码 代码如下:

@array = 5..9;
push(@array,0);
foreach $t (@array) {
print $t;
}

注意,push 的第一个参数或 pop 的唯一参数必须是数组变量。

7. shift 和 unshift 操作

push/pop 操作的是数组末尾,而 shiftunshift 则操作数组开头(也就是下标最小的那一端)。shift 取出并返回第一个元素,unshift 将元素插入到开头。

8. 将数组插入字符串

数组可以像标量一样直接放入双引号字符串中:

复制代码 代码如下:

@rocks = qw{wawa kaka haha};
print "@rocks";

此时元素之间会自动以空格分隔。

9. Perl 最常用的默认变量:$_

$_ 是 Perl 中使用最广泛的默认变量。很多操作在没有明确指定变量时,会自动使用 $_

复制代码 代码如下:

$_ = "yahoo google baidu";
print;

它会打印出 "yahoo google baidu"。

10. reverse 操作

reverse 返回输入列表的反转顺序,但它不会修改原数组:

复制代码 代码如下:

@fred = 6..10;
@barney = reverse(@fred);
print "@barney";

如果反转后的结果没有赋值给任何变量,那这次操作就没有实际意义。

11. sort 操作

sort 根据内部的字符顺序对列表进行排序:

复制代码 代码如下:

@rocks = qw/ bedrock slate rubble granite /;
@sorted = sort(@rocks);
print "@sorted";

12. 标量和列表上下文

上下文是 Perl 中非常重要的概念。同一个表达式在标量上下文和列表上下文中的行为可能完全不同:

复制代码 代码如下:

@people = qw( fred barney betty );
@sorted = sort @people;
$number = 42 + @people;

print "@sorted";#列表context:barney , betty, fred
print "\n";
print "$number";#标量context:42+3,得到45

13. 在标量 Context 中使用 List-Producing 表达式

reverse 用在标量上下文时,它会把整个列表当作字符串反转:

复制代码 代码如下:

@backwards = reverse qw / yabba dabba doo /;
print "@backwards"; #返回doo, dabba, yabba

print "\n";
$backwards = reverse qw/ yabba dabba doo /;
print "$backwards"; #返回oodabbadabbay

14. 在列表 Context 中使用 Scalar-Producing 表达式

如果表达式产生的是标量值,当它出现在列表上下文时,会自动转换成一个单元素列表:

复制代码 代码如下:

@fred = 6*7;
@barney = "hello".' '. "world";

print "@fred"; #返回42
print "@barney"; #返回hello world

15. 强制转换为标量 Context

当你需要标量上下文,但 Perl 默认给你列表上下文时,可以用 scalar 函数强制转换:

复制代码 代码如下:

@rocks = qw(talc quartz jade obsidian);
print "How many rocks do you ha ve?\n";
print "I ha ve ", @rocks, "rocks!\n"; #错误,输出rocks 的名字
print "I ha ve ", scalar @rocks, "rocks!\n"; #正确,输出其数字

注意,Perl 没有对应的函数能强制转换为列表上下文,因为上下文是由表达式所在的位置决定的。

本文转载于:https://www.jb51.net/article/60779.htm 如有侵犯,请联系zhengruancom@outlook.com删除。
免责声明:正软商城发布此文仅为传递信息,不代表正软商城认同其观点或证实其描述。

产品推荐

热门关注