Forum |  HardWare.fr | News | Articles | PC | S'identifier | S'inscrire | Shop Recherche
1244 connectés 

  FORUM HardWare.fr
  Programmation
  Python

  Itérer "discrètement" sur un élément

 


 Mot :   Pseudo :  
 
Bas de page
Auteur Sujet :

Itérer "discrètement" sur un élément

n°1857923
guybrush02
Posté le 05-03-2009 à 12:05:05  profilanswer
 

Bonjour,
 
Dans le cadre d'une itération sur un élément, je souhaite savoir comment itérer "discrètement", sans instancier de variable inutile. J'explique :  
J'ai quelque part une classe implémentant un algorithme séquenciel. Cet algorithme avance étape par étape par un appel à un générateur implicite (dans le cas présent, considérons qu'un appel à "next" sur un objet issu de cette classe fournisse un itérateur faisant évoluer l'algorithme étape par étape). Cette méthode ne retourne rien, seul l'état interne de l'algo est modifié à chaque étape.  
 
La façon la plus évidente et la plus simple d'obtenir le résultat final de cet algorithme semble être :

Code :
  1. for x in algo.next():
  2.   pass


Où est le problème ? En réalité, il n'y en a pas : ça fonctionne, c'est suffisament explicite mais... par convention, les outils de vérification de code signalent qu'il y a une variable inutilisée "x". Alors, ce n'est pas un problème en soit, mais c'était suffisant pour attiser ma curiosité :  
 - Quelles seraient les méthodes alternatives pour parcourir l'ensemble d'un itérable (attention, ça peut être un générateur sans sentinelle, donc pas de builtin iter(iterable, sentinel) ici) sans avoir une variable inutilisée ?
 
Bien entendu, je souhaiterai que tout cela reste lisible, explicite et concis (donc pas de map avec une fonction identité, par exemple).

mood
Publicité
Posté le 05-03-2009 à 12:05:05  profilanswer
 

n°1857935
masklinn
í dag viðrar vel til loftárása
Posté le 05-03-2009 à 12:22:36  profilanswer
 

  • Appeler next() n'a aucun intérêt ici, si algo est un itérable, alors for x in algo: pass est largement suffisant pour effectuer l'itération intégrale.
  • Il est possible de forcer l'évaluation d'un itérateur en le transformant en liste (list(algo)), malheureusement ça n'est pas nécessairement clair sur le but de l'opération, dans la mesure où aucune liste ne sera récupérée ou utilisée.
  • Le plus clair serait probablement de créer une fonction evaluate (pouvant être simplement définie comme evaluate = list, ou evaluate = functools.partial(map, lambda _: None)) qui servira à forcer l'évaluation de l'itérateur.


Enfin, iter ne sert de toute façon pas à forcer une évaluation, aucun intérêt ici.

 

Enfin, je ne vois pas l'intérêt de présenter l'algo sous la forme d'un itérateur si on ne peut rien en faire et si l'itérateur ne sert à rien.

Message cité 1 fois
Message édité par masklinn le 05-03-2009 à 12:23:57

---------------
Stick a parrot in a Call of Duty lobby, and you're gonna get a racist parrot. — Cody
n°1857940
guybrush02
Posté le 05-03-2009 à 12:42:14  profilanswer
 

masklinn a écrit :

  • Appeler next() n'a aucun intérêt ici, si algo est un itérable, alors for x in algo: pass est largement suffisant pour effectuer l'itération intégrale.
  • Il est possible de forcer l'évaluation d'un itérateur en le transformant en liste (list(algo)), malheureusement ça n'est pas nécessairement clair sur le but de l'opération, dans la mesure où aucune liste ne sera récupérée ou utilisée.
  • Le plus clair serait probablement de créer une fonction evaluate (pouvant être simplement définie comme evaluate = list, ou evaluate = functools.partial(map, lambda _: None)) qui servira à forcer l'évaluation de l'itérateur.

)


 - Comme je l'ai dit, next() ne fait que retourner un itérateur, c'est pour l'exemple. Effectivement, un objet issu de cette classe modélisant ma séquence est itérable et "in algo" est largement suffisant.  
 - Le problème en passant par une liste (que ce soit via une compréhension ou ta fonction partielle reposant sur un map), c'est l'espace occupé en mémoire. La séquence pouvant être (potentiellement infiniment) longue. Repasser par un générateur ne ferait que déplacer le problème. Un reduce serait plus adapté, d'un point de vue consommation, mais tout aussi peu clair.  
 
 
 
Présenter l'algorithme sous forme d'itérateur me permet d'analyser chaque étape de l'algorithme (je rappelle qu'il s'agit de la construction d'une séquence) en vérifiant l'état interne de l'objet (état qui serait trop conséquent à fournir en output de l'itérateur ou à mémoriser complètement). L'exemple du premier message n'est qu'un cas particulier dans lequel je souhaite obtenir le résultat de cet algorithme sans considérer chacune des étapes.

n°1857943
masklinn
í dag viðrar vel til loftárása
Posté le 05-03-2009 à 12:48:19  profilanswer
 

guybrush02 a écrit :

- Le problème en passant par une liste (que ce soit via une compréhension ou ta fonction partielle reposant sur un map), c'est l'espace occupé en mémoire. La séquence pouvant être (potentiellement infiniment) longue. Repasser par un générateur ne ferait que déplacer le problème. Un reduce serait plus adapté, d'un point de vue consommation, mais tout aussi peu clair.


Je ne vois pas ce qui t'empeche d'adapter la 3e proposition en définissant evaluate différement. Ca peut être à base de reduce, ou avec une boucle for qui ne fait rien, aucune importance [:petrus75]


---------------
Stick a parrot in a Call of Duty lobby, and you're gonna get a racist parrot. — Cody
n°1857946
guybrush02
Posté le 05-03-2009 à 12:55:13  profilanswer
 

masklinn a écrit :


Je ne vois pas ce qui t'empeche d'adapter la 3e proposition en définissant evaluate différement. Ca peut être à base de reduce, ou avec une boucle for qui ne fait rien, aucune importance [:petrus75]


C'est pas faux  :)  
Mais définir une fonction evaluate juste pour dire de ne pas avoir une variable inutilisée, bof :-)
J'avoue, ma question initiale est purement académique. J'imaginais qu'il devait me manquer une petite astuce en Python permettant d'itérer sans variable.  
 
En fait, après réflexion, la question initiale pourrait être formulée plus simplement :  
Soit g un buffer/générateur, comment épuiser g ?  
 
... et les réponses seraient les mêmes :-)

n°1857950
masklinn
í dag viðrar vel til loftárása
Posté le 05-03-2009 à 13:00:06  profilanswer
 

guybrush02 a écrit :

Mais définir une fonction evaluate juste pour dire de ne pas avoir une variable inutilisée, bof :-)


Ne pas avoir une variable inutilisée, et exprimer clairement que l'intérêt réside dans les effets de bord générés par l'itérateur et non dans les valeurs retournées par celui-ci [:spamafote]

guybrush02 a écrit :

J'imaginais qu'il devait me manquer une petite astuce en Python permettant d'itérer sans variable.


Je n'ai jamais eu un besoin pareil, je présume que la grande majorité de la communauté Python est dans ce cas, et les rares fois où ce cas est rencontré ils appellent simplement list, ou une variante.


---------------
Stick a parrot in a Call of Duty lobby, and you're gonna get a racist parrot. — Cody
n°1858175
elsed
Posté le 05-03-2009 à 18:44:35  profilanswer
 

Si tu peux implementer une fonction has_next, une solution propre et programmatiquement élégante pourrait etre :
 

Code :
  1. while ( algo.has_next() ):
  2.     algo.next()

n°1858179
masklinn
í dag viðrar vel til loftárása
Posté le 05-03-2009 à 19:02:38  profilanswer
 

elsed a écrit :

Si tu peux implementer une fonction has_next, une solution propre et programmatiquement élégante pourrait etre :
 

Code :
  1. while ( algo.has_next() ):
  2.     algo.next()



On a franchement pas les mêmes définitions de "propre" ou "programmatiquement élégant" [:pingouino]


---------------
Stick a parrot in a Call of Duty lobby, and you're gonna get a racist parrot. — Cody
n°1858192
guybrush02
Posté le 05-03-2009 à 19:39:25  profilanswer
 

Pareil que Masklinn  :)
 
Edité : et même un while algo: pass ne serait pas élégant, bien que dans mon cas, il ne serait pas difficile de retourner une valeur de vérité :-)


Message édité par guybrush02 le 05-03-2009 à 19:40:50
n°1858379
elsed
Posté le 06-03-2009 à 10:16:09  profilanswer
 

masklinn a écrit :


On a franchement pas les mêmes définitions de "propre" ou "programmatiquement élégant" [:pingouino]


 
 
son probleme n'est pas du tout un probleme d'iterateur :
 
en renommant les methodes ça paraitra peut-etre plus clair :
 
   1. while ( algo.has_next_step() ):
   2.     algo.execute_next_step()
 
y'a pas plus simple et plus lisible.

mood
Publicité
Posté le 06-03-2009 à 10:16:09  profilanswer
 

n°1858389
masklinn
í dag viðrar vel til loftárása
Posté le 06-03-2009 à 10:37:22  profilanswer
 

elsed a écrit :

y'a pas plus simple et plus lisible.


Code :
  1. algo.execute()


[:spamafote]


Message édité par masklinn le 06-03-2009 à 10:37:33

---------------
Stick a parrot in a Call of Duty lobby, and you're gonna get a racist parrot. — Cody
n°1858392
elsed
Posté le 06-03-2009 à 10:42:06  profilanswer
 


Code :
  1. def execute():
  2.    while ( algo.has_next_step() ):
  3.        algo.execute_next_step()


 
 
huhu !
 :)

n°1858394
masklinn
í dag viðrar vel til loftárása
Posté le 06-03-2009 à 10:45:57  profilanswer
 

elsed a écrit :


Code :
  1. def execute():
  2.    while ( algo.has_next_step() ):
  3.        algo.execute_next_step()


 
 
huhu !
 :)


http://forum.hardware.fr/hfr/Progr [...] m#t1857943
[:draculax_tt]


---------------
Stick a parrot in a Call of Duty lobby, and you're gonna get a racist parrot. — Cody
n°1858438
guybrush02
Posté le 06-03-2009 à 12:29:29  profilanswer
 

Ce que je fais, c'est déjà définir une méthode "apply" sur l'algo, et c'est le contenu de cette méthode qui pour l'instant ne fait qu'un simple for x in self: pass.  
 
Calculatoirement, cela me coute autant de vérifier l'existence d'une étape supplémentaire que de la calculer. (Et vu la nature de l'algorithme, que je n'ai pas détaillé, je ne peux pas me permettre de calculer l'étape suivante, vérifier si le résultat est cohérent, retourner l'étape actuelle, mémoriser la suivante ;).

n°1890944
NaPs
Posté le 03-06-2009 à 15:08:30  profilanswer
 

Pour éviter que les outils de vérification de code ralent si tu n'utilises pas la variable dans le bloc, il me semble que la convention est d'utiliser "_" comme nom de variable.
 
Cela dit, il y a surement un moyen plus joli pour faire fonctionner ton algo.

n°1890946
guybrush02
Posté le 03-06-2009 à 15:11:53  profilanswer
 

Malheureusement, _ génère également un avertissement (deux, par ailleurs, car _ est considéré comme un nom de variable inapproprié).  
 
Pour l'algo, effectivement, il s'agit juste de sucre "syntaxique" pour le résultat. Mais la question était plutot d'ordre général que spécifique à ma "problématique".  
 
Merci ;)

n°1890948
NaPs
Posté le 03-06-2009 à 15:13:56  profilanswer
 

Tu utilises pylint ?

n°1890950
guybrush02
Posté le 03-06-2009 à 15:16:17  profilanswer
 

Pychecker et pylint.  
Je ne sais plus de mémoire lequel (si ce n'est les deux ?) qui indiquait cela.

n°1890961
NaPs
Posté le 03-06-2009 à 15:24:02  profilanswer
 

Je parlais de ça en fait (retrouvé dans l'aide de pylint) :
 

   --dummy-variables-rgx=<regexp>
                        A regular expression matching names used
                        for dummy variables (i.e. not used). [current:
                        _|dummy]


 
Enfin bon si ça t'aides pas :)

n°1890979
guybrush02
Posté le 03-06-2009 à 15:36:11  profilanswer
 

Curieux, j'ai l'erreur qui se produit encore (enfin, l'avertissement) et je ne trouve pas ton passage dans l'aide de pylint. Par contre, un tour sur la page man via Google me donne bien cela. Je vais mettre à jour, je suppose que cela vient de là.


Aller à :
Ajouter une réponse
  FORUM HardWare.fr
  Programmation
  Python

  Itérer "discrètement" sur un élément

 

Sujets relatifs
[jQuery] Sélectionner le dernier élément sélectionné.Pourquoi ne pas pointer vers un élément courant dans une liste chainée
[XSL] Traitement différent dernier élément d'une listeVerifier la présence d'un élément dans une liste
Javscript : Savoir si le curseur est a l'exterieur d'un elementRetouver le form englobant sans partir d'un element
[Excel] Rechercher un élément différent - RésoluPosistion élément sélectionné dans une combo
Etat d'un element du menusupprimer un élément de ma table de string
Plus de sujets relatifs à : Itérer "discrètement" sur un élément


Copyright © 1997-2022 Hardware.fr SARL (Signaler un contenu illicite / Données personnelles) / Groupe LDLC / Shop HFR