列表和数组有什么区别?

时间:2012-12-22 09:42:16

标签: arrays perl list

this页面上,它显示了如何初始化数组,如果向下滚动一下,在“列表”部分下,它“解释”列表是什么以及它们与数组的不同之处

除了它使用的例子与声明一个数组完全相同,并且不解释它。

有什么区别?

8 个答案:

答案 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]来引用匿名数组。
  • 如果您创建列表切片,则可以索引列表(以获取其 n 元素)而不创建数组,因此(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