http://qs1969.pair.com?node_id=130861

There appears to be a subtle difference between a list and an array in Perl, but I am having trouble understanding the distinction. I have read that an array is a container for a list, but I am not sure what that means. What is the container for a hash called?

Replies are listed 'Best First'.
(tye)Re: What is the difference between a list and an array?
by tye (Sage) on Dec 11, 2001 at 10:42 UTC

    I think of an array as a variable that can hold a list of scalar values. The term "list" can mean any number of things in Perl. I suggest you reread a thread you participated in a long time ago: Scalars, Lists, and Arrays.

    Many of the meanings of "list" in Perl come close to "a list of scalar values", but that still doesn't nail things down very specifically. You can have:

    • a "list literal" might be used to mean "a list of scalar-value expressions separated by commas and surrounded by parens"
    • a list of SVs arranged together in memory, such as on the stack
    • "an operation that would return a list of scalar values if used in a list context"
    • the argument list passed to a subroutine
    • I don't yet have a good label for what goes between the parens in a foreach statement -- it is naively a "list of scalar values" but is functionally much more like an "argument list" but calling it the latter would confuse people (stolen form (tye)Re3: tr doesn't *really* use a list)
    (tye)Re3: List context or not? has some more of my thoughts on "lists" in Perl.

    But there are a few things that make an array different from a listlike thing that isn't an array:

    • The @ character can be used to introduce an array (if you can't use @ with what you have, then you don't have an array)
    • This means that you can use an array with push, pop, shift, unshift, and splice.
    • You can get a reference to an entire array. You can't get a reference to an entire non-array "list" except using [ ... ] which is cheating because it makes a new array, copies the "list" into it, and then gives you back a reference to the new array.
    You see, an array is like a list of scalar values with an extra chunk of data that keeps track of bookkeeping information about where the list is, how much space is allocated for the list, etc. This means that you can add items to the list of values stored in an array because the that extra chunk of data allows the array to reallocate space to make more room. Then everyone who is using that array knows where the list of values had to be moved to when more room was required.

    If you want to add values to a list that isn't an array, then you really end up making a new larger list that contains the values (or copies of the values) from the original list.

    A hash is like an array. You could think of it as a container for a list of pairs (where each pair is one string and one scalar value). If you take the contents of a hash out of the hash, you have a "list" (of scalar values, every other one of which must be just a string).

    Also note that Perl gives you a way to find specific elements of a list (the "list slice" -- (list)[1,2]) but there is no way to "use a list as a hash" other than creating a (perhaps temporary) hash.

    Also, a "list" is a rather temporary thing. If you want to find out how many things are in a list, you can do:     my $size= ()= LIST; but now you've lost the "list" and so you'll either have to recreate or keep a copy of it. And about the only way to keep a copy of it is to stuff it into an array. Similarly, if you want the last item of a list, you can use     my $last= (LIST)[-1]; but you had better not have wanted to know anything else about the list as you've now lost it again.

    Sure, you can get several items out of the list at once using a list slice. But you can't get several items out of the list and also record the size of the list unless you put the list into an array at least temporarilly. And you can't do a lot of other things like use the first element of the list as the index of which element of the list you want to grab. Even passing a list into a function causes Perl to place that list into an array (@_) for you. (:

            - tye (but my friends call me "Tye")
(crazyinsomniac) Re: What is the difference between a list and an array?
by crazyinsomniac (Prior) on Dec 11, 2001 at 10:49 UTC
    A list is, well, just that, a list, a bunch of values separated by commas. An array is a data structure -- a "variable".

    Consider this:

    for my $thing("this","Is","aA","List") { print "$thing\n"; } print "\---------\n"; my @things = ("this","Is","aA","List","being","assigned","to","an","ar +ray"); for my $thing(@things) { print "$thing\n"; } print "\---------\n"; my %things = ("this", "Is", "aA", "List", "being", "assigned", "to", "a", "hash", "and", "as", "such", "it", "must", "be", "EVEN!", ,); for my $thing(@things) { print "$thing\n"; }
    Furthermore, the distinction between a list and an array goes to context. There are two context's in perl, list, and scalar. The scalar function forces scalar context. The for (@something) "construct" implies list construct, as do functions and other things. To get a better grip on context in perl, please read japhys excellent article from perlmonth.com Issue 9: "List" is a Four-Letter Word (local) (remote).

     
    ___crazyinsomniac_______________________________________
    Disclaimer: Don't blame. It came from inside the void

    perl -e "$q=$_;map({chr unpack qq;H*;,$_}split(q;;,q*H*));print;$q/$q;"

      A list is, well, just that, a list, a bunch of values separated by commas.

      You may be failing to address the confusion between what a list is with its literal representation in a program. After all a "bunch of values separated by commas" is considered a list literal, where the commas are mere notational conveniences. To the program itself, a list is a series of values, nevermind how they got there.

      This is NOT a flame! It goes more to highlighting the difference between what a thing is (e.g., list), and what you have to write in a program to get one.

      This particular distinction (or more precisely, the failure to understand it) caused more problems for me early on than maybe anything else (one exception: learning that my means local--in the C/C++ sense of the word--and that local really means localized global, or having a temporary local value for one But I digress).

      Fortunately for me, Perl's forgiving nature (combined with its uncanny "do what I mean" quality) saved my skin more than once. But when I later went back to examine some of my old code, I could see evidence of my then-incomplete understanding of these concepts.

      dmm

      You can give a man a fish and feed him for a day ...
      Or, you can
      teach him to fish and feed him for a lifetime

      crazyinsomniac:

      Truly, I meant no harm, in "Re(2) (crazyinsomniac): What is the difference between a list and an array?," above. Please consider it an (apparently unsuccessful) attempt at constructive criticism.

      I was hoping to articulate how your explanation might have perhaps obfuscated more than illuminated the subject for me, given my own understanding (or lack thereof) back when I was struggling with this concept myself, and in so doing, perhaps assist sierrathedog04 (et al) in that endeavor.

      dmm

      You can give a man a fish and feed him for a day ...
      Or, you can
      teach him to fish and feed him for a lifetime
Re: What is the difference between a list and an array?
by japhy (Canon) on Dec 11, 2001 at 09:11 UTC
    Ugh, sticky situation. I think my definition is that an array is a mutable list -- one that can have element insertions or deletions. The elements of a list are mutable (as in ($a,$b) = ($b,$a)) but the list itself is fixed. An array is a list that has operations available on it (such as "what is your size?" and "remove the last element").

    Hashes are special -- there's no real non-hash hash-like structure in Perl that I can think of.

    _____________________________________________________
    Jeff[japhy]Pinyan: Perl, regex, and perl hacker.
    s++=END;++y(;-P)}y js++=;shajsj<++y(p-q)}?print:??;

Re: What is the difference between a list and an array?
by mischief (Hermit) on Dec 11, 2001 at 19:24 UTC
    Hello,

    There is a good explanation in perlfaq4:

           What is the difference between a list and an array?
    
    An array has a changeable length. A list does not. An array is something you can push or pop, while a list is a set of values. Some people make the distinction that a list is a value while an array is a variable. Subroutines are passed and return lists, you put things into list con- text, you initialize arrays with lists, and you foreach() across a list. "@" variables are arrays, anonymous arrays are arrays, arrays in scalar context behave like the num- ber of elements in them, subroutines access their argu- ments through the array "@_", and push/pop/shift only work on arrays. As a side note, there's no such thing as a list in scalar context. When you say $scalar = (2, 5, 7, 9); you're using the comma operator in scalar context, so it uses the scalar comma operator. There never was a list there at all! This causes the last value to be returned: 9.
Re: What is the difference between a list and an array?
by belg4mit (Prior) on Dec 11, 2001 at 09:09 UTC
    Arrays and hashes can both be used as lists, witness:
    my %F = (a=>1, b=>2, c=>3); my @F = qw(a 1 b 2 c 3); foo(%F); foo(@F);
    #New simpler code to avoid slices my %F = (a=>1); my @F = qw(a 1); foo(%F); foo(@F);
    Within each code block both calls to foo pass the same values; @_(the parameters list) will be the same. NOTE: It is luck that the first works, as it relies upon the particular key/value pairs and how the current implementation of hashes in perl works.

    Basically an array is an actual thing that lives somewhere and has an address (you can get a glob for it, you can use a reference to it), but that is not so for a list.

    UPDATE: Modified code to ensure hash order prompted by dmmiller2k's reply. Which of course makes the comparison a little less clear since it uses slices. Added a second code block to reclarify

    UPDATE I am an idiot. The sliced version only returned the values. And it did in fact work as advertised to begin with. It was just lucky that it did so. Added the NOTE, I really do understand this, but apparently I'm not very good at explaining it with code ;-)

    --
    perl -p -e "s/(?:\w);([st])/'\$1/mg"

      Just to add my voice to this cacophany ...

      If I recall my own confusion on this point correctly, and the explanation that helped me finally turn the corner (toward understanding), a "list" may be described as a context, or a way of interpreting "thingys" (or variables), rather than as a thingy in its own right, whereas an array is one of three types of containers (thingys) your program may use to hold other thingys (information).

      For example, an array, <CODE<>@a</CODE>, containing the three values, 'a', 'b' and 'c' (or @a = ('a', 'b', 'c')); in scalar context (in other words when the context requires a single value), it will evaluate as 3 (its number of elements). An example of this is a simple assignment to a scalar:

      $x = @a;  # will contain 3

      On the other hand, in list context (or, when the context permits multiple scalar values), the array will be flattened into a series of values of its elements, as in the classic case, when it is passed as a parameter to a (non-prototyped1) sub:

      my_sub( @a ); # ... sub my_sub { # here the localized @_ variable contains references to # the list of values passed as paramters, for my $i (0 .. $#_) { print "param $i = $_[$i]\n"; } } # OUTPUT # param 0 = a # param 1 = b # param 2 = c

      (Hashes may also be similarly flattened into lists, where the key/value pairs are guaranteed to remain adjacent and in 'key', 'value' order, but the ordering of the pairs is not necessarily deterministic.)

      If array thingys and hash thingys and scalars are all intermingled in a given list context, they are all flattened into a single list of all the individual elements:

      @a = ( 'I', 'am' ); %h = ( 'perl' => 'hacker' ); $x = 'just'; my_sub( @a, $x, 'another', %h ); # OUTPUT: # param 0 = I # param 1 = am # param 2 = just # param 3 = another # param 4 = perl # param 5 = hacker

      1 Prototypes can alter this behavior, but that's a whole 'nother conversation.

      dmm

      You can give a man a fish and feed him for a day ...
      Or, you can
      teach him to fish and feed him for a lifetime
Re: What is the difference between a list and an array?
by Hanamaki (Chaplain) on Dec 11, 2001 at 21:14 UTC
Re: What is the difference between a list and an array?
by fmogavero (Monk) on Dec 11, 2001 at 23:55 UTC
    Excellent question!

     Washington, Lincoln, Jefferson is a list.

     @streets  = (Washington, Lincoln, Jefferson) or  @presidents  = (Washington, Lincoln, Jefferson) make the list an array.

    I've always thought of lists as an unnamed group of items whereas an array is a named group of items.

    Does someone have any other elaborations for this?

Re: What is the difference between a list and an array?
by tradez (Pilgrim) on Dec 12, 2001 at 00:19 UTC
    Basic difference is if I set
    $scalar = @array;
    I get the number of elemets in the array. However if I do
    i $scalar = @list;
    I get the first value of the list popped into this scalar value.
      Actually, those are both arrays. You might also amend the last sentence after running this code:
      my $scalar = (1, 2, 4, 8); print "Have: $scalar\n";
        List is something which is nothing but a group of scalar variables separated by comma(,). In order to use the list in PERL, we need to declare it in an array variable, prefixed by "@", or a hash variable prefixed by "%".