答案 0 :(得分:8)
实际上,这个问题在Perl's FAQ中得到了很好的回答。列表是(一种)组织Perl源代码中的数据的方法。数组是一种类型的存储数据;哈希是另一个。
这里的差异非常明显:
my @arr = (4, 3, 2, 1);
my $arr_count = @arr;
my $list_count = (4, 3, 2, 1);
print $arr_count, "\n"; # 4
print $list_count; # 1
乍一看,这里有两个相同的清单。但请注意,只有分配给@arr
变量的变量才能通过标量赋值正确计算。 $list_count
存储1 - 使用comma
运算符计算表达式的结果(它基本上为我们提供了枚举中的最后一个表达式 - 1)。
请注意,列表运算符/函数与数组之间存在轻微(但非常重要)的区别:前者是一种杂食,因为它们不会更改源数据,后者则不会。例如,您可以安全地切片并加入列表,如下所示:
print join ':', (4,2,3,1)[1,2];
...但是试图“弹出”它会给你一个很有说服力的信息:
pop (4, 3, 2, 1);
### Type of arg 1 to pop must be array (not list)...
答案 1 :(得分:8)
数组是一种变量。它包含0个或更多个单调增加索引的标量。例如,以下内容创建数组@a
:
my @a;
作为变量,您可以操纵数组。您可以添加元素,更改元素的值等。
“列表”意味着很多东西。它的两个主要用途是引用列表值和列表运算符的实例。
列表值是堆栈上零个或多个标量的有序集合。例如,以下代码中的sub返回要分配给@a
(数组)的列表。
my @a = f();
无法操纵列表值;它们被任何经过它们的操作员全部吸收。它们就是如何在子和运算符之间传递值。
列表运算符(,
)是一个N-ary运算符*,它依次计算每个操作数。在列表上下文中,列表运算符返回一个列表,该列表包含由其操作数返回的列表的合并。例如,以下代码段中的列表运算符返回一个列表值,该值包含数组@a
和@b
的所有元素:
my @c = ( @a, @b );
(顺便说一句,parens不会创建列表。它们只是覆盖优先级。)
你不能操纵列表操作符,因为它是代码。
* - 文档说这是一个二元运算符(至少在标量上下文中),但事实并非如此。
答案 2 :(得分:8)
看看perldoc -q "list and an array"
。最大的区别是数组是变量,但Perl的所有数据类型(标量,数组和散列)都可以提供列表,它只是一个有序集合标量。
考虑这段代码
use strict;
use warnings;
my $scalar = 'text';
my @array = (1, 2, 3);
my %hash = (key1 => 'val1', key2 => 'val2');
test();
test($scalar);
test(@array);
test(%hash);
sub test { printf "( %s )\n", join ', ', @_ }
输出此
( )
( text )
( 1, 2, 3 )
( key2, val2, key1, val1 )
Perl子例程将列表作为其参数。在第一种情况下,列表为空;在第二个它有一个元素( $scalar)
;在第三个列表中,列表与@array
的大小相同,并且包含( $array[0], $array[1], $array[2], ...)
,在最后一个列表两次作为错误,因为%hash
中的元素数量,并包含( 'key1', $hash{key1}, 'key2', $hash{key2}, ...)
。
显然,列表可以通过多种方式提供,包括标量变量,标量常量和子程序调用结果的混合,例如
test($scalar, $array[1], $hash{key2}, 99, {aa => 1, bb => 2}, \*STDOUT, test2())
我希望很明显这样的列表与数组非常不同。
将数组视为列表变量会有帮助吗?标量文字和标量变量之间很少有区别。例如:
my $str = 'string';
my $num = 99;
很明显,'string'
和99
是文字,而$str
和$num
是变量。这里的区别是相同的:
my @numbers = (1, 2, 3, 4);
my @strings = qw/ aa bb cc dd /;
其中(1, 2, 3, 4)
和qw/ aa bb cc dd /
是列表文字,而@numbers
和@strings
是变量。
答案 3 :(得分:3)
简单展示差异。
sub getarray{ my @x = (2,4,6); return @x; }
sub getlist { return (2,4,6); }
现在,如果您这样做:
my @a = getarray();
my @b = getlist();
然后@a
和@b
都会包含相同的值 - 列表(2,4,6)
。但是,如果你这样做:
my $a = getarray();
my $b = getlist();
然后$a
将包含值3,而$b
将包含值6.
所以是的,您可以说数组是包含列表值的变量,但这并不能说明整个故事,因为数组和文字列表有时会表现得完全不同。
答案 4 :(得分:3)
列表是逗号分隔值(csv)或表达式(cse)。数组(和散列)是容器。
可以通过列表初始化数组或散列:
@a = ("profession", "driver", "salary", "2000");
%h = ("profession", "driver", "salary", "2000");
可以返回一个列表:
sub f {
return "moscow", "tel-aviv", "madrid";
}
($t1, $t2, $t3) = f();
print "$t1 $t2 $t3\n";
($ t1,$ t2,$ t3)是标量容器$ t1,$ t2,$ t3的列表。
列表是编写perl表达式(语法的一部分)的一种形式,而数组是数据结构(内存位置)。
答案 5 :(得分:2)
列表和数组之间的区别让很多人感到困惑。 Perl本身错误地将其内置函数wantarray()弄错了:"此函数本应该被命名为wantlist()。" perlfaq4中有一个答案"What is the difference between a list and an array?",但它并没有结束我的困惑。
我现在相信这些是真的:
\(2, 4, 6)
返回列表中标量的引用列表。您可以使用[2, 4, 6]
来引用匿名数组。(2, 4, 6)[1]
为4。但是如果我想计算列表中的元素,或者获取数组的最后一个元素呢?我应该以某种方式在数组和列表之间进行转换吗?
您始终可以使用[...]
语法将列表转换为数组。计算列表中元素的一种方法是创建一个匿名数组,然后立即在标量上下文中取消引用它,如下所示:
sub list { return qw(carrot stick); }
my $count = @{[list()]};
print "Count: $count\n"; # Count: 2
另一种方法是使用列表赋值运算符,如下所示:
sub list { return qw(carrot stick); }
my $count = (()=list());
print "Count: $count\n"; # Count: 2
此代码中有 no array ,但列表赋值运算符返回分配的内容数。我将它们分配给一个空的变量列表。在代码高尔夫中,我编写()=$str=~/reg/g
来计算某些字符串中的正则表达式匹配。
您无需将数组转换为列表,因为列表上下文中的数组已经是列表。如果你想要数组的最后一个元素,只需说$array[-1]
。
逗号运算符将返回列表的最后一个元素,但我无法使用它来获取数组的最后一个元素。如果我在标量上下文中说((),@array)
,那么@array
处于标量上下文中,我得到了计数。
您无需为索引列表创建数组。您可以创建一个匿名数组,如[list()]->[1]
中所示,或者您可以创建一个列表切片,如(list())[1]
中所示。我在列表切片方面遇到了麻烦,因为它们的语法不同。列表切片需要括号!在C或Python或Ruby中,func()[1]
将对函数的返回值执行数组索引,但在Perl中,func()[1]
是语法错误。您必须说(func())[1]
。
例如,我想打印数组中第3个最高的数字。因为我懒惰,我对数组进行排序并采用第三个最后一个元素:
my @array = (112, 101, 114, 108, 32, 104, 97, 99, 107);
print +(sort { $a <=> $b } @array)[-3], "\n"; # prints 108
一元+
阻止print()函数窃取我的括号。
您可以在数组上使用列表切片,如(@array)[1]
中所示。这是有效的,因为数组是一个列表。列表和数组之间的区别在于数组可以$array[1]
。
答案 6 :(得分:0)
数组与列表比较
列表是与数组不同的数据结构。
最大的区别在于直接访问与顺序访问的概念。数组允许两者;直接和顺序访问,而列表仅允许顺序访问。这是因为这些数据结构存储在内存中的方式。
此外,列表的结构不像数组那样支持数字索引。而且,不需要像在数组中那样在内存中相邻分配元素。
数组
数组是项目的有序集合,其中数组中的每个项目都有一个索引。
答案 7 :(得分:-1)
here my answer about sigils and context
但主要区别在于:
数组的scalar-context-value
类似count of elements
。
列表中有一个scalar-context-value
,如LAST element in list
。
所以,您需要了解goat-operator
:=()=
。
用法?
perl -e '$s =()= qw(a b c); print $s' # uh? 3? (3 elements, array context)
perl -e '$s = qw(a b cLastElementThatYouSee); print $s' # uh? cLastElementThatYouSee? (list context, last element returned)
如您所见,=()=
将上下文更改为array