Vraag Wat is het verschil tussen lijsten en arrays?


Op deze pagina, laat het zien hoe een array geïnitialiseerd moet worden, en als je een beetje naar beneden scrolt, onder de sectie genaamd "De lijsten", "legt" het uit welke lijsten zijn en hoe ze verschillen van arrays.

Behalve dat het een voorbeeld gebruikt dat precies hetzelfde is als het declareren van een array, en het helemaal niet verklaart.

Wat is het verschil?


10
2017-12-22 09:42


oorsprong


antwoorden:


Kijk eens naar perldoc -q "list and an array". Het grootste verschil is dat een array een is veranderlijk, maar alle gegevenstypen van Perl (scalar, array en hash) kunnen een lijst, dat is gewoon een geordende set scalaires.

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

welke dit uitvoert

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

Een Perl-subroutine neemt een lijst als zijn parameters. In het eerste geval is de lijst leeg; in de tweede heeft het een enkel element ( $scalar); in de derde is de lijst even groot als @array en bevat ( $array[0], $array[1], $array[2], ...)en in de laatste is het tweemaal zo lastig als het aantal elementen in %hash, en bevat ( 'key1', $hash{key1}, 'key2', $hash{key2}, ...).

Het is duidelijk dat deze lijst op verschillende manieren kan worden geleverd, waaronder een combinatie van scalaire variabelen, scalaire constanten en het resultaat van subroutine-aanroepen, zoals

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

en ik hoop dat het duidelijk is dat zo'n lijst heel anders is dan een array.

Zou het helpen om aan arrays te denken als lijstvariabelen? Er is zelden een probleem om onderscheid te maken tussen scalaire letterlijke waarden en scalaire variabelen. Bijvoorbeeld:

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

het is duidelijk dat 'string' en 99 zijn letterlijk $str en $num zijn variabelen. En het onderscheid is hier hetzelfde:

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

waar (1, 2, 3, 4) en qw/ aa bb cc dd / zijn lijst letterlijk, terwijl @numbers en @strings zijn variabelen.


8
2017-12-22 20:00



Een array is een type variabele. Het bevat 0 of meer elementen bestaande uit een niet-negatieve geheeltallig sleutel en een scalaire waarde. Bijvoorbeeld,

my @a;

Als variabelen kun je arrays manipuleren. U kunt elementen toevoegen, de waarden van elementen wijzigen, enz.


"Lijst" betekent veel dingen. De twee primaire toepassingen voor deze zijn om te verwijzen naar lijstwaarden en lijstoperators.

Een lijstwaarde is een geordende verzameling van nul of meer scalar's op de stapel. De sub in de volgende code retourneert bijvoorbeeld een lijst waaraan moet worden toegewezen @a (een array).

my @a = f();

Lijstwaarden kunnen niet worden gemanipuleerd; ze worden volledig opgenomen door elke operator waaraan ze worden doorgegeven. Ze zijn precies hoe waarden worden doorgegeven tussen subs en operatoren.


De lijstoperator is een N-ary-operator * die om de beurt elk van zijn operand evalueert. In lijstcontext retourneert de lijstoperator een lijst die bestaat uit een samenvoeging van de lijsten die door de operanden worden geretourneerd. De volgende lijstoperator retourneert bijvoorbeeld een lijstwaarde die bestaat uit alle elementen van arrays @a en @b:

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

(Trouwens, parens maken geen lijsten, ze zijn er alleen om de prioriteit op te heffen.)

U kunt een lijstoperator niet manipuleren omdat het code is.


* - De documenten zeggen dat het een binaire operator is (althans in scalaire context), maar het is niet waar.


8
2017-12-22 18:06



Eigenlijk is deze vraag heel goed beantwoord in Veelgestelde vragen over Perl. Lijsten zijn (een van) methoden om de gegevens in de Perl-broncode te ordenen. Arrays zijn een type opslaggegevens; hashes zijn een andere.

Het verschil is hier vrij duidelijk:

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

Op het eerste gezicht zijn hier twee identieke lijsten. Merk echter op dat alleen degene waaraan is toegewezen @arr variabele wordt correct geteld door scalaire toewijzing. De $list_count slaat 1 op - het resultaat van het evalueren van expressie met comma operator (die ons in feite de laatste expressie in die opsomming geeft - 1).

Merk op dat er een klein (maar zeer belangrijk) verschil is tussen lijstoperatoren / -functies en matrix-eenheden: de eerste zijn soort van alleseters, omdat ze de brongegevens niet wijzigen, de laatste niet. U kunt bijvoorbeeld veilig op uw lijst plakken en eraan deelnemen, zoals dit:

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

... maar als je probeert te 'poppen', krijg je een nogal sprekende boodschap:

pop (4, 3, 2, 1);
### Type of arg 1 to pop must be array (not list)...

8
2017-12-22 09:43



Eenvoudige demonstratie van verschil.

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

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

Nu, als u zoiets doet als dit:

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

Dan @a en @b bevatten beide dezelfde waarde - de lijst (2,4,6). Als u dit echter doet:

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

Dan $a zal de waarde 3 bevatten, terwijl $b bevat de waarde 6.

Dus ja, je kunt zeggen dat arrays variabelen zijn die lijstwaarden bevatten, maar dat zegt niet het hele verhaal, want arrays en letterlijke lijsten gedragen zich soms heel anders.


3
2017-12-22 21:23



Lijsten zijn door komma's gescheiden waarden (csv) of uitdrukkingen (cse). Arrays (en hashes) zijn containers.

Men kan een array of hash initialiseren door een lijst:

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

Men kan een lijst terugsturen:

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

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

($ t1, $ t2, $ t3) is een lijst met scalaire containers $ t1, $ t2, $ t3.

Lijsten zijn een vorm van schrijven perl-expressies (een deel van de syntaxis), terwijl arrays datastructuren (geheugenlocaties) zijn.


2
2018-03-18 09:18



Het verschil tussen lijsten en arrays verwart veel. Perl heeft het zelf verkeerd door de ingebouwde functie verkeerd te benoemen wantarray (): "In plaats daarvan moet deze functie de gewenste lijst () heten." Er is een antwoord in perlfaq4, "Wat is het verschil tussen een lijst en een array?", maar het maakte geen einde aan mijn verwarring.

Ik geloof nu dat deze waar zijn:

  • Een array in scalaire context wordt een telling van de elementen ervan.
  • De komma-operator in scalaire context retourneert het laatste element.
  • U kunt geen verwijzing naar een lijst maken; \(2, 4, 6) geeft een lijst met verwijzingen naar de scalaires in de lijst. Je kunt gebruiken [2, 4, 6] om een ​​verwijzing naar een anonieme array te maken.
  • U kunt een lijst indexeren (om het te krijgen nth element) zonder een array te maken als je een list slice maakt, dus (2, 4, 6)[1] is 4.

Maar wat als ik de elementen in een lijst wil tellen of het laatste element van een array wil krijgen? Moet ik op de een of andere manier tussen arrays en lijsten converteren?

Je kan altijd converteer een lijst naar een array met [...] syntaxis. Een manier om de elementen in een lijst te tellen, is door een anonieme array te maken en deze vervolgens onmiddellijk te de-leiden in scalaire context, zoals:

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

Een andere manier is om de operator voor lijsttoewijzing te gebruiken, zoals:

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

Er bestaat geen array in deze code, maar de operator voor lijsttoewijzing retourneert het aantal dingen dat wordt toegewezen. Ik wijs ze toe aan een lege lijst met variabelen. In code golf schrijf ik ()=$str=~/reg/g om de reguliere expressie-overeenkomsten in een reeks te tellen.

Je hoeft niet converteer een array naar een lijst, omdat een array in lijstcontext al een lijst is. Als u het laatste element van een array wilt, hoeft u alleen maar te zeggen $array[-1].

De komma-operator zou het laatste element van een lijst retourneren, maar ik kan het niet gebruiken om het laatste element van een array te krijgen. Als ik zeg ((),@array) in scalaire context, dan @array is in scalaire context en ik krijg de telling.

Je hoeft geen array te maken indexeer een lijst. U kunt een anonieme array maken, zoals in [list()]->[1], of u kunt een lijstschijf maken, zoals in (list())[1]. Ik had problemen met lijstschijven omdat ze verschillende syntaxis hebben. Een lijstsegment heeft haakjes nodig! In C of Python of Ruby, func()[1] zou de array-index uitvoeren op de retourwaarde van de functie, maar in Perl, func()[1] is een syntaxisfout. Je moet zeggen (func())[1].

Ik wil bijvoorbeeld het derde hoogste getal in serie afdrukken. Omdat ik lui ben, sorteer ik de array en neem ik het derde laatste element:

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

De unary + voorkomt dat de functie print () mijn ronde haakjes steelt.

U kunt een lijstschijf in een array gebruiken, zoals in (@array)[1]. Dit werkt omdat een array een lijst is. Het verschil tussen lijsten en arrays is dat arrays kunnen doen $array[1].


2
2018-04-07 01:34



hier mijn antwoord over sigils en context

maar het belangrijkste verschil is dit:

matrices hebben een scalar-context-value graag willen count of elements.

lijsten hebben een scalar-context-value graag willen LAST element in list.

dus je moet het weten goat-operator: =()=.

Gebruik?

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)

zoals je ziet, =()= verander context in array


-1
2017-12-22 11:28