IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Langage Perl Discussion :

boucle foreach sur une liste de listes


Sujet :

Langage Perl

  1. #1
    Membre confirmé Avatar de iblis
    Inscrit en
    Janvier 2007
    Messages
    510
    Détails du profil
    Informations personnelles :
    Âge : 57

    Informations forums :
    Inscription : Janvier 2007
    Messages : 510
    Points : 570
    Points
    570
    Par défaut boucle foreach sur une liste de listes
    Bonjour – et bon muget.

    Je stocke un couple de données dans une liste de la manière suivante :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    while ( $page =~ m{<span class="headlines">(.*?)</span>.*?(/multimedia/ta/.*\.ram)}g ) {
    #  print "$1 $2\n";
        push @list, [$2, $1];
    }
    Je n'ai pas de problème pour accéder aux élements directement : $list[$i][0] et $list[$i][1].

    Mais je voudrais y accéder avec une boucle foreach et là, perl et moi ne parlons plus la même langue.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    foreach my @pair (@list){
      print "$pair[0] $pair[1]\n";
    }
    ne veut rien dire pour le compilateur car les éléments doivent être des scalaires. Mais
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    foreach my $pair (@list){
      print "$pair[0] $pair[1]\n";
    }
    ne va pas non plus puisqu'il n'y pas de liste @pair (merci à strict et warnings).
    Je n'arrive pas non plus à accéder aux doublets avec un shift (ce que je veux faire en fait ailleurs dans le code) : ni @pair = shift @list ni $pair = shift @list ne donne le résultat espéré avec print "@pair" ou print $pair.

    J'y perd un peu mon latin. Si quelqu'un pouvait m'expliquer.

  2. #2
    Membre confirmé Avatar de iblis
    Inscrit en
    Janvier 2007
    Messages
    510
    Détails du profil
    Informations personnelles :
    Âge : 57

    Informations forums :
    Inscription : Janvier 2007
    Messages : 510
    Points : 570
    Points
    570
    Par défaut
    En fait, je commence à comprendre. Il faut indiquer que le scalaire est (une référence à) une liste.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    foreach my $pair (@list){
      print "@{$pair}[0] @{$pair}[1]\n";
    }
    et
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    print "@{shift @list}\n";

  3. #3
    Expert éminent
    Avatar de Jedai
    Homme Profil pro
    Enseignant
    Inscrit en
    Avril 2003
    Messages
    6 245
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Côte d'Or (Bourgogne)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Avril 2003
    Messages : 6 245
    Points : 8 586
    Points
    8 586
    Par défaut
    Tu peux également écrire ceci comme cela (syntaxe souvent préférée, bien qu'il s'agisse surtout d'une question de goût) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    foreach my $pair (@list){
      print "$pair->[0] $pair->[1]\n";
    }
    Même système pour les références de hachage.
    Néanmoins la flèche n'est indispensable que pour le premier niveau, si tu as une référence $ref sur un tableau de référence sur des hachages, tu peux visiter les valeurs ainsi :
    (mettre la flèche "$ref->[0]->{clé}" est possible, simplement pas nécessaire car il n'y a pas d'ambiguïté possible)

    --
    Jedaï

  4. #4
    Membre confirmé Avatar de iblis
    Inscrit en
    Janvier 2007
    Messages
    510
    Détails du profil
    Informations personnelles :
    Âge : 57

    Informations forums :
    Inscription : Janvier 2007
    Messages : 510
    Points : 570
    Points
    570
    Par défaut
    Merci pour les explications, Jedai.

    Est-ce à dire que, formellement au moins, une liste de listes (ou un tableau de tableaux) est une table de hachage ?

    C'est en tous cas très pratique de pouvoir penser et utiliser les structures en question de plusieurs points de vue. Même si j'avoue que les questions de contexte me perturbent parfois.

  5. #5
    Membre confirmé Avatar de iblis
    Inscrit en
    Janvier 2007
    Messages
    510
    Détails du profil
    Informations personnelles :
    Âge : 57

    Informations forums :
    Inscription : Janvier 2007
    Messages : 510
    Points : 570
    Points
    570
    Par défaut
    Par exemple quelle est la différence réelle entre les affectations suivantes ?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    # soit : 
    my @list = (['a1', 'a2'], ['b1', 'b2']);
     
    my $p = $list[0];
    my @q = $list[0];
    Apparemment dans les deux cas, c'est la référence au premier élément de @list, c'est à dire l'adresse de ['a1', 'a2'] qui est affectée à la variable. Alors que j'eus attendu un $p valant 2 (la longueur de la liste, à cause du contexte scalaire) et l'affectation de la référence uniquement dans le second cas (contexte liste).

    Bon ben si $p->[0] (ou @{$p}[0], peu importe) et $q[0][0] ont finalement la même valeur ('a1' en l'occurrence), quelle est la vraie différence entre $p et @q ?

    Je sais pas si cela fait avancer le schmilblique pour d'autres. Pour moi, sans aucun doute. Donc merci d'avance pour les réponses à mes questions tordues.

  6. #6
    Expert éminent
    Avatar de Jedai
    Homme Profil pro
    Enseignant
    Inscrit en
    Avril 2003
    Messages
    6 245
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Côte d'Or (Bourgogne)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Avril 2003
    Messages : 6 245
    Points : 8 586
    Points
    8 586
    Par défaut
    Citation Envoyé par iblis
    Est-ce à dire que, formellement au moins, une liste de listes (ou un tableau de tableaux) est une table de hachage ?
    Non, une liste de liste (ou plus correctement un tableau de tableau, liste est un concept différent de tableau en Perl) est en réalité un tableau de références sur des tableaux, et associe donc un couple d'indices numérique à une valeur, tandis qu'une table de hachage associe un indice chaîne de caractère à une valeur. Il est aisé de simuler un tableau de tableau par un hachage, mais ce n'est pas efficace.

    --
    Jedaï

  7. #7
    Expert éminent
    Avatar de Jedai
    Homme Profil pro
    Enseignant
    Inscrit en
    Avril 2003
    Messages
    6 245
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Côte d'Or (Bourgogne)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Avril 2003
    Messages : 6 245
    Points : 8 586
    Points
    8 586
    Par défaut
    Citation Envoyé par iblis
    Par exemple quelle est la différence réelle entre les affectations suivantes ?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    # soit : 
    my @list = (['a1', 'a2'], ['b1', 'b2']);
     
    my $p = $list[0];
    my @q = $list[0];
    Apparemment dans les deux cas, c'est la référence au premier élément de @list, c'est à dire l'adresse de ['a1', 'a2'] qui est affectée à la variable. Alors que j'eus attendu un $p valant 2 (la longueur de la liste, à cause du contexte scalaire) et l'affectation de la référence uniquement dans le second cas (contexte liste).
    Non, à vrai dire le contexte important dans ton opération est indiqué par le $ dans $list[0], qui lui indique déjà qu'on veut récupérer un scalaire. Après cela l'affectation ne fait que mettre ce scalaire dans un autre contexte (et dans un contexte de liste, un scalaire agit comme une liste à un élément).
    A propos, sais-tu ce qu'est @list[0] ?

    Citation Envoyé par iblis
    Bon ben si $p->[0] (ou @{$p}[0], peu importe) et $q[0][0] ont finalement la même valeur ('a1' en l'occurrence), quelle est la vraie différence entre $p et @q ?
    La vraie différence ? Tu peux rajouter des éléments à @q, tu ne peux pas en rajouter à $p (bien sûr tu peux toujours en rajouter à @$p ou à @{$q[0]}, c'est la même chose). Cela me semble une différence notable !

    --
    Jedaï

  8. #8
    Membre confirmé Avatar de iblis
    Inscrit en
    Janvier 2007
    Messages
    510
    Détails du profil
    Informations personnelles :
    Âge : 57

    Informations forums :
    Inscription : Janvier 2007
    Messages : 510
    Points : 570
    Points
    570
    Par défaut
    Citation Envoyé par Jedai
    Non, une liste de liste (ou plus correctement un tableau de tableau, liste est un concept différent de tableau en Perl) est en réalité un tableau de références sur des tableaux, et associe donc un couple d'indices numérique à une valeur, tandis qu'une table de hachage associe un indice chaîne de caractère à une valeur. Il est aisé de simuler un tableau de tableau par un hachage, mais ce n'est pas efficace.
    C'est parfaitement clair. Merci bien.

  9. #9
    Membre confirmé Avatar de iblis
    Inscrit en
    Janvier 2007
    Messages
    510
    Détails du profil
    Informations personnelles :
    Âge : 57

    Informations forums :
    Inscription : Janvier 2007
    Messages : 510
    Points : 570
    Points
    570
    Par défaut
    Citation Envoyé par Jedai
    A propos, sais-tu ce qu'est @list[0] ?
    Là, ça se corse un peu. D'abord parce que mon compilateur n'aime pas trop (en fait, j'étais déjà tombé dessus lors de mes tâtonnements) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Scalar value @list[0] better written as $list[0] at exolibre.12.2.1.pl line 22.
    Ensuite apparemment (print @list[0]) contient l'adresse de la première paire.

    Mais le debugger ne veut rien entendre :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
      DB<4> x $list[0]
    0  ARRAY(0x83ee14c)
       0  'a1'
       1  'a2'
    Là tout va bien, mais :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
      DB<8> x @list[0]
    Unrecognized character \xC2 at (eval 13)[/usr/share/perl/5.8/perl5db.pl:628] line 2.
     at (eval 13)[/usr/share/perl/5.8/perl5db.pl:628] line 2
            eval '($@, $!, $^E, $,, $/, $\\, $^W) = @saved;package main; $^D = $^D | $DB::db_stop;
      @list?[0];
     
    ;' called at /usr/share/perl/5.8/perl5db.pl line 628
            DB::eval called at /usr/share/perl/5.8/perl5db.pl line 3410
            DB::DB called at exolibre.1.1.0.pl line 10
    Par contre :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
      DB<11> print @list[0]
    ARRAY(0x83ee14c)
      DB<12> print $list[0]
    ARRAY(0x83ee14c)
    Mais c'est peut être moi qui fait un mauvais usage de l'évaluateur !


    Citation Envoyé par Jedai
    La vraie différence ? Tu peux rajouter des éléments à @q, tu ne peux pas en rajouter à $p (bien sûr tu peux toujours en rajouter à @$p ou à @{$q[0]}, c'est la même chose). Cela me semble une différence notable !
    D'accord, donc $ et @ sont vraiment des marqueurs de classe grammaticale ; et en l'occurrence ($list[0], @$p) ils servent à indiquer si la référence doit être traitée comme un scalaire (premier exemple) ou une liste (second exemple).

    Merci en tous cas pour le cours en ligne

  10. #10
    Expert éminent
    Avatar de Jedai
    Homme Profil pro
    Enseignant
    Inscrit en
    Avril 2003
    Messages
    6 245
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Côte d'Or (Bourgogne)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Avril 2003
    Messages : 6 245
    Points : 8 586
    Points
    8 586
    Par défaut
    Citation Envoyé par iblis
    Là, ça se corse un peu. D'abord parce que mon compilateur n'aime pas trop (en fait, j'étais déjà tombé dessus lors de mes tâtonnements) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Scalar value @list[0] better written as $list[0] at exolibre.12.2.1.pl line 22.
    Ensuite apparemment (print @list[0]) contient l'adresse de la première paire.
    En fait @list[0] est une liste (pas un tableau) à un élément, ce qui se comporte comme $list[0]...
    @list[0,1] par contre est une liste à 2 éléments, d'indices 0 et 1 dans @list, ce que l'on appelle une "tranche" de tableau ('slice' en anglais). Les tranches sont très pratiques, on peut mettre une liste arbitraire en indice d'une tranche, l'indice d'une tranche est évalué en contexte de liste.
    On peut également faire des tranches de hachages :
    @my_hash{'key1', 'keys2'}

    On peut assigner à une tranche, ce qui peut-être extrèmement pratique, par exemple si on a une liste de mot-clé qu'on veut mettre en tant que clé dans un hachage temporaire (bonne technique pour supprimer les doublons entre autres) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    my %temp; @temp{@keywords} = (1) x @keywords;
    --
    Jedaï

  11. #11
    Membre confirmé Avatar de iblis
    Inscrit en
    Janvier 2007
    Messages
    510
    Détails du profil
    Informations personnelles :
    Âge : 57

    Informations forums :
    Inscription : Janvier 2007
    Messages : 510
    Points : 570
    Points
    570
    Par défaut
    Super.

    Simplement je ne comprends pas la notation (1) x @keywords. Je vais me replonger dans la doc.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Critère d'une requête sur une colonne de liste modifiable
    Par curt dans le forum Requêtes et SQL.
    Réponses: 2
    Dernier message: 03/08/2008, 21h31
  2. Le "]" sur une zone de liste déroulante
    Par VITALTH dans le forum IHM
    Réponses: 5
    Dernier message: 28/03/2008, 09h50
  3. critère d'une requête basé sur une zone de liste
    Par hellyjlj dans le forum Requêtes et SQL.
    Réponses: 10
    Dernier message: 15/11/2007, 09h01
  4. Autosize sur une zone de liste
    Par Pierot86 dans le forum VBA Access
    Réponses: 0
    Dernier message: 09/08/2007, 10h21
  5. se déplacer sur une zone de liste
    Par bb62 dans le forum IHM
    Réponses: 12
    Dernier message: 31/01/2005, 10h47

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo