12

On this page, it shows how to initialize an array, and if you scroll down a bit, under the section called "The Lists" it "explains" what lists are and how they're different from arrays.

Except it uses an example that's just exactly the same as declaring an array, and doesn't explain it whatsoever.

What is the difference?

temporary_user_name
  • 35,956
  • 47
  • 141
  • 220
  • Your reference is misleading. It says *an array is just a set of scalars*, whereas there is far more to it than that – Borodin Dec 22 '12 at 19:51
  • And also less than that, as `#!math {2, 3, 2}` is not a set. – darch Dec 22 '12 at 20:32
  • @darch: I think the mathematical notion of a *set* is irrelevant here. – Borodin Dec 22 '12 at 22:03
  • 3
    I think that page that you refer to is rather confusing. "Lists are really a special type of array" is **nonsense** in my opinion. Perl has three types of variables: scalars, arrays and hashes. Lists are just what they sound like: A list of scalars. Like you have a shopping LIST, which is a list of items you need to buy. No need to complicate things. – TLP Dec 22 '12 at 22:50

8 Answers8

10

Take a look at perldoc -q "list and an array". The biggest difference is that an array is a variable, but all of Perl's data types (scalar, array and hash) can provide a list, which is simply an ordered set of scalars.

Consider this code

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 ', ', @_ }

which outputs this

(  )
( text )
( 1, 2, 3 )
( key2, val2, key1, val1 )

A Perl subroutine takes a list as its parameters. In the first case the list is empty; in the second it has a single element ( $scalar); in the third the list is the same size as @array and contains ( $array[0], $array[1], $array[2], ...), and in the last it is twice as bug as the number of elements in %hash, and contains ( 'key1', $hash{key1}, 'key2', $hash{key2}, ...).

Clearly that list can be provided in several ways, including a mix of scalar variables, scalar constants, and the result of subroutine calls, such as

test($scalar, $array[1], $hash{key2}, 99, {aa => 1, bb => 2}, \*STDOUT, test2())

and I hope it is clear that such a list is very different from an array.

Would it help to think of arrays as list variables? There is rarely a problem distinguishing between scalar literals and scalar variables. For instance:

my $str = 'string';
my $num = 99;

it is clear that 'string' and 99 are literals while $str and $num are variables. And the distinction is the same here:

my @numbers = (1, 2, 3, 4);
my @strings = qw/ aa bb cc dd /;

where (1, 2, 3, 4) and qw/ aa bb cc dd / are list literals, while @numbers and @strings are variables.

temporary_user_name
  • 35,956
  • 47
  • 141
  • 220
Borodin
  • 126,100
  • 9
  • 70
  • 144
8

Actually, this question is quite well answered in Perl's FAQ. Lists are (one of) methods to organize the data in the Perl source code. Arrays are one type of storing data; hashes are another.

The difference is quite obvious here:

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

At first sight, there are two identical lists here. Note, though, that only the one that is assigned to @arr variable is correctly counted by scalar assignment. The $list_count stores 1 - the result of evaluating expression with comma operator (which basically gives us the last expression in that enumeration - 1).

Note that there's a slight (but very important) difference between list operators/functions and array ones: the former are kind-of omnivores, as they don't change the source data, the latter are not. For example, you can safely slice and join your list, like this:

print join ':', (4,2,3,1)[1,2]; 

... but trying to 'pop' it will give you quite a telling message:

pop (4, 3, 2, 1);
### Type of arg 1 to pop must be array (not list)...
temporary_user_name
  • 35,956
  • 47
  • 141
  • 220
raina77ow
  • 103,633
  • 15
  • 192
  • 229
  • 1
    So arrays are variables holding lists, by definition. So they really are the same thing, for all practical concerns. – temporary_user_name Dec 22 '12 at 09:44
  • 5
    @aerovistae No, they are plainly not the same thing. Lists and arrays can behave quite differently (as above), and grasping the difference is crucial to writing non-buggy Perl. – darch Dec 22 '12 at 12:17
  • I think this answer needs a discussion of `return @x` versus `return (1, 3)` before I am wholly happy with it, btb. – darch Dec 22 '12 at 12:22
  • 3
    Talking about list count is non-sense and misleading. I disapprove. – ikegami Dec 22 '12 at 18:06
  • 2
    Your last example is severely flawed. Change `4` to `$x` and you get no error (in 5.16). Your example doesn't show what you claim it does. – ikegami Dec 22 '12 at 18:11
  • 1
    @Aerovistae, No, arrays are variables holding *scalar values*. You can assign values to an array by assigning a list to it, but they don't hold a list. Lists and arrays are not remotely similar, a far cry from "the same thing" – ikegami Dec 22 '12 at 18:12
  • 3
    @Aerovistae: Arrays and lists are no more the "same thing" than scalar variables and strings or numbers. – Borodin Dec 23 '12 at 03:07
  • Coming back to this, I just want to say that this example is *very, very* far from clear to people who are new to Perl. Whatever you're seeing here, it's utterly obfuscated. – temporary_user_name Nov 06 '13 at 17:55
8

An array is a type of variable. It contains 0 or more scalars at monotonously increasing indexes. For example, the following creates array @a:

my @a;

Being variables, you can manipulate arrays. You can add elements, change the values of elements, etc.


"List" means many things. The two primary uses for it are to refer to list values and instances of the list operator.

A list value is an ordered collection of zero or more scalars on the stack. For example, the sub in the following code returns a list to be assigned to @a (an array).

my @a = f();

List values can't be manipulated; they are absorbed in whole by any operator to which they are passed. They are just how values are passed between subs and operators.


The list operator (,) is an N-ary operator* that evaluates each of its operands in turn. In list context, the list operator returns a list consisting of an amalgamation of the lists returned by its operands. For example, the list operator in the following snippet returns a list value consisting of all the elements of arrays @a and @b:

my @c = ( @a, @b );

(By the way, parens don't create lists. They're just there to override precedence.)

You cannot manipulate a list operator since it's code.


* — The docs say it's a binary operator (at least in scalar context), but it's not true.

ikegami
  • 367,544
  • 15
  • 269
  • 518
  • What is a list operator? The comma? Isn't the comma present in arrays also, as well as hashes? – temporary_user_name May 17 '17 at 21:25
  • @Aerovistae, Re "*What is a list operator?*", Another name for the comma operator. /// Re "*Isn't the comma present in arrays also, as well as hashes?*", What? – ikegami May 17 '17 at 22:37
  • Both a hash and an array may have commas in them: `(1, 2)` or `("key" => "value", "key2" => "value2")`. I'm not sure what my point is anymore. Sigh. Perl is different. – temporary_user_name May 17 '17 at 22:38
  • I guess my point is that it's somewhat hard to tell when the comma operator is going to just separate things and when it's going to cause the list to only return the last element. – temporary_user_name May 17 '17 at 22:41
  • @Aerovistae, Those aren't arrays or hashes; both of those are instances of the comma operator (returning either the last value or all values depending on context.) Arrays and hashes are types of variables, and those aren't variables. – ikegami May 17 '17 at 23:10
  • So, if my understanding is correct, `@a = (1,2,7); $b = @a;` will result in `$b` being `3` (the length of the array), while `$b = (1, 2, 7)` will result in `$b` being `7`, because comma operator only returns the last value in the list since it's a scalar context. Is that right? – temporary_user_name May 17 '17 at 23:14
  • @Aerovistae, Exactly. – ikegami May 18 '17 at 01:22
  • Thank you again for being profoundly helpful when I was struggling with perl two years ago. I really appreciated it. You gave far clearer and less disdainful answers than anyone else here. – temporary_user_name Mar 01 '19 at 20:55
3

Simple demonstration of difference.

sub getarray{ my @x = (2,4,6); return @x; }

sub getlist { return (2,4,6); }

Now, if you do something like this:

 my @a = getarray();
 my @b = getlist();

Then @a and @b will both contain the same value - the list (2,4,6). However, if you do this:

my $a = getarray();
my $b = getlist();

Then $a will contain the value 3, while $b will contain the value 6.

So yes, you can say that arrays are variables containing list values, but that doesn't tell the whole story, because arrays and literal lists behave quite differently at times.

Mark Reed
  • 91,912
  • 16
  • 138
  • 175
3

Lists are comma-separated values (csv) or expressions (cse) . Arrays (and hashes) are containers.

One can initialize an array or hash by a list:

@a = ("profession", "driver", "salary", "2000");
%h = ("profession", "driver", "salary", "2000");

One can return a list:

sub f {
    return "moscow", "tel-aviv", "madrid";
}

($t1, $t2, $t3) = f();
print "$t1 $t2 $t3\n";

($t1, $t2, $t3) is a list of scalar containers $t1, $t2, $t3.

Lists are a form of writing perl expressions (part of syntax) while arrays are data structures (memory locations).

rlib
  • 7,444
  • 3
  • 32
  • 40
2

The difference between lists and arrays confuses many. Perl itself got it wrong by misnaming its builtin function wantarray(): "This function should have been named wantlist() instead." There is an answer in perlfaq4, "What is the difference between a list and an array?", but it did not end my confusion.

I now believe these to be true:

  • An array in scalar context becomes a count of its elements.
  • The comma operator in scalar context returns the last element.
  • You can't make a reference to a list; \(2, 4, 6) returns a list of references to the scalars in the list. You can use [2, 4, 6] to make a reference to an anonymous array.
  • You can index a list (to get its nth element) without making an array if you make a list slice, so (2, 4, 6)[1] is 4.

But what if I want to count the elements in a list, or get the last element of an array? Should I convert between arrays and lists somehow?

You can always convert a list to an array with [...] syntax. One way to count the elements in a list is to make an anonymous array, then immediately dereference it in scalar context, like so:

sub list { return qw(carrot stick); }
my $count = @{[list()]};
print "Count: $count\n";  # Count: 2

Another way is to use the list assignment operator, like so:

sub list { return qw(carrot stick); }
my $count = (()=list());
print "Count: $count\n";  # Count: 2

There is no array in this code, but the list assignment operator returns the number of things being assigned. I assign them to an empty list of variables. In code golf, I write ()=$str=~/reg/g to count the regular expression matches in some string.

You need not convert an array to a list, because an array in list context is already a list. If you want the last element of an array, just say $array[-1].

The comma operator would return the last element of a list, but I can't use it to get the last element of an array. If I say ((),@array) in scalar context, then @array is in scalar context and I get the count.

You need not make an array to index a list. You can make an anonymous array, as in [list()]->[1], or you can make a list slice, as in (list())[1]. I had trouble with list slices because they have different syntax. A list slice needs parentheses! In C or Python or Ruby, func()[1] would do the array index on the function's return value, but in Perl, func()[1] is a syntax error. You must say (func())[1].

For example, I want to print the 3rd highest number in array. Because I'm lazy, I sort the array and take the 3rd last element:

my @array = (112, 101, 114, 108, 32, 104, 97, 99, 107);
print +(sort { $a <=> $b } @array)[-3], "\n";  # prints 108

The unary + prevents the print() function stealing my parentheses.

You can use a list slice on an array, as in (@array)[1]. This works because an array is a list. The difference between lists and arrays is that arrays can do $array[1].

George Koehler
  • 1,560
  • 17
  • 23
0

An Array Vs A List

A list is a different kind of data structure from an array.

The biggest difference is in the idea of direct access Vs sequential access. Arrays allow both; direct and sequential access, while lists allow only sequential access. And this is because the way that these data structures are stored in memory.

In addition, the structure of the list doesn’t support numeric index like an array is. And, the elements don’t need to be allocated next to each other in the memory like an array is.

Arrays

An array is an ordered collection of items, where each item inside the array has an index.

Muhammed Haris
  • 340
  • 1
  • 5
  • 15
  • Of all the things call list, a linked list is the least likely thing being discussed (in a Perl context). – ikegami Mar 03 '19 at 07:05
-2

here my answer about sigils and context

but main difference is this:

arrays have a scalar-context-value like count of elements.

lists have a scalar-context-value like LAST element in list.

so, you need to know about goat-operator: =()=.

Usage?

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)

as you see, =()= change context to array

Community
  • 1
  • 1
gaussblurinc
  • 3,642
  • 9
  • 35
  • 64