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

Python Discussion :

Nommer des objets en série


Sujet :

Python

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Rédacteur
    Avatar de Zavonen
    Profil pro
    Inscrit en
    Novembre 2006
    Messages
    1 772
    Détails du profil
    Informations personnelles :
    Âge : 77
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 1 772
    Par défaut Nommer des objets en série
    Bonjour à tous !
    Voici mon problème:
    J'ai une liste d'objets créés en grand nombre par un constructeur appelé dans une boucle.
    Je peux accéder à ces objets par leur indice dans la liste.
    A côté de cela j'ai une liste de chaines (étiquettes) en correspondance avec la liste des objets.
    Je voudrais pouvoir nommer dans une boucle mes objets avec les étiquettes de la liste de chaines.
    Exemple ma liste d'objets:
    L1=[ ... , ...., ...., ... ]
    Ma liste d'étiquettes:
    L2=['un','deux', ......]
    Au lieu de référencer le premier objet par L1[0] j'aimerais le référencer par 'un', un peu comme si j'avais instancié par
    un= Truc( , ..) si ma classe est Truc.
    Je n'ai rien trouvé dans la doc officielle.
    Quelqu'un sait faire ?
    Ce qu'on trouve est plus important que ce qu'on cherche.
    Maths de base pour les nuls (et les autres...)

  2. #2
    Membre Expert
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    1 418
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 1 418
    Par défaut
    Il n'est pas expliqué dans la question ce que signifie "en correspondance".
    En supposant que la correspondance d'un élément A de L1 avec un élément B de L2 signifie que L1.index(A) = L2.index(B) ( A et B ont le même rang dans leur liste respective), alors j'aurais tendance à proposer
    qui permet de remplacer
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    for el2 in L2:
        i = L2.index(el2)
        el1 = L1[i]
    par
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    for el2 in L2:
        el1 = d[el2]
    L'ennui est évidemment que d n'est pas ordonné selon L2 alors que L1 est ordonné selon [0,1,2,3,4,5...].
    Ce qui m'a ainsi d'abord gêné, c'est que pour conserver la connaissance de l'ordre contenue dans la nature de liste pour L1, il faut garder à portée de main la liste L2 qui tient lieu d'indices.
    Mais en réfléchissant, finalement, la nécessité de recourir à xrange(y) quand on veut parcourir L1 n'est pas différente de la nécessité de recourir à L2 quand on veut parcourir d.

    La vraie différence est en réalité qu'on ne peut pas écrire
    d.index(el1) alors qu'on peut écrire L1.index(el1)
    ce qui signifie qu'on ne peut pas remonter d'un élément el1 de d à un imaginaire rang appartenant à L2 de cet élément dans d en faisant d.index(el1).

    Je ne sais pas si ma réponse est bien en correspondance avec la question mais j'ai l'impression que celle-ci revient à chercher un dictionnaire ordonné. Or, pour autant que je sache, cela n'existe encore pas dans Python.

  3. #3
    Membre éprouvé
    Profil pro
    Inscrit en
    Juillet 2008
    Messages
    76
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Juillet 2008
    Messages : 76
    Par défaut
    Salut !

    J'utiliserais tout simplement un dictionnaire, en partant du principe qu'il y a autant d'éléments dans chaque liste et que leurs indices correspondes:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    # -*- coding: latin-1 -*-
     
    class Truc:
            # Un objet quelconque...
    	def __init__(self, machin):
    		self.machin = machin
    # Les deux listes contenant les objets et leurs étiquettes
    L1 = [Truc('truc'), Truc('bidule'), Truc('chose')]
    L2 = ['Ga', 'Bu', 'Zo']
     
    # Dictionnaire pour associer les objets et leurs étiquettes
    dico = {}
    for i in range(len(L1)):
     
    	dico[ L2[i] ] = L1[i]
     
    # Afficher le résultat	
    for e in dico:
    	print e + ": " + str(dico[e])

  4. #4
    Rédacteur
    Avatar de Zavonen
    Profil pro
    Inscrit en
    Novembre 2006
    Messages
    1 772
    Détails du profil
    Informations personnelles :
    Âge : 77
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 1 772
    Par défaut
    Merci pour vos réponses, mais ce n'est pas exactement ce que je veux.
    Si je reprends le code de clic4, et que j'écris par exemple:
    Ga ou bien [Ga]. Je me retrouve avec:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    Traceback (most recent call last):
      File "/home/gilles/sources_python/etiqettes.py", line 21, in <module>
        L=[Ga]
    NameError: name 'Ga' is not defined
    Je voudrais pouvoir utiliser Ga à la place de L1[0]. Donc en fait faire comme si j'avais déclaré: Ga=Truc('truc')
    Ce qu'on trouve est plus important que ce qu'on cherche.
    Maths de base pour les nuls (et les autres...)

  5. #5
    Membre Expert Avatar de pacificator
    Profil pro
    Inscrit en
    Août 2006
    Messages
    1 074
    Détails du profil
    Informations personnelles :
    Âge : 45
    Localisation : France

    Informations forums :
    Inscription : Août 2006
    Messages : 1 074
    Par défaut
    en utilisant globals?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    >>> liste1 = range(1, 6)
    >>> liste2 = ['un', 'deux', 'trois', 'quatre', 'cinq']
    >>> globals().update(zip(liste2, liste1))
    >>> un
    1
    >>> deux
    2

  6. #6
    Rédacteur
    Avatar de Zavonen
    Profil pro
    Inscrit en
    Novembre 2006
    Messages
    1 772
    Détails du profil
    Informations personnelles :
    Âge : 77
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 1 772
    Par défaut
    Citation Envoyé par pacificator
    en utilisant globals?
    YES !!!!
    Merci pour ce coup de baguette magique ! Cela résout exactement mon problème.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    # -*- coding: latin-1 -*-
     
    class Truc:
            # Un objet quelconque...
    	def __init__(self, machin):
    		self.machin = machin
    # Les deux listes contenant les objets et leurs étiquettes
    L1 = [Truc('truc'), Truc('bidule'), Truc('chose')]
    L2 = ['Ga', 'Bu', 'Zo']
     
    globals().update(zip(L2,L1))
     
    print Ga
    Ce qu'on trouve est plus important que ce qu'on cherche.
    Maths de base pour les nuls (et les autres...)

  7. #7
    Membre Expert
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    1 418
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 1 418
    Par défaut
    Je ne suis en rien étonné que m'a proposition ne soit pas la bonne solution. Je me doutais bien que ça allait être comme ça, parce que je sais très bien que je suis encore novice en Python.
    Mais c'est seulement avec la solution de pacificator que je m'aperçois que je n'avais même pas compris le problème, et qu'au delà de ce problème je n'avais pas encore bien saisi certaines notions fondamentales.

    Mais je trouve qu'aussi bien la réponse de pacificator que la question de Zavonen, de par la façon dont elles sont rédigées, recouvrent d'un voile tamisant les intéressantes choses à en tirer, alors même qu'elles sont fort subtiles et intéressantes. Enfin, moi je trouve que le problème est subtil et que le décortiquer est intéressant.... C'est parce que je suis novice.....

    ------------

    Tout d'abord la réponse de pacificator:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    globals().update(zip(liste2, liste1))
    ce n'est rien d'autre que
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    dico = dict(zip(liste2,liste1))
    for u in dico:
        globals()[u] = dico[d]
    c'est à dire qu'il s'agit en fait de faire rentrer dans le dictionnaire globals() de nouveaux items u:dico[u] qui n'y sont pas.
    En allant au plus simple, en se passant même de tout dictionnaire et de toute boucle, cela se réduit à
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    a = 'soleil'
    diametre = 1391000
    print globals()
    globals()['annee'] = 2009
    globals()['zwi':'paf']
    print
    print globals()
     
    print
    print annee
    qui affiche
    {'a': 'soleil', '__builtins__': <module '__builtin__' (built-in)>, '__file__': 'C:\\Python25\\Lib\\idlelib\\idle.pyw', 'idlelib': <module 'idlelib' from 'C:\Python25\lib\idlelib\__init__.pyc'>, 'diametre': 1391000, '__name__': '__main__', '__doc__': None}

    {'a': 'soleil', 'zwi': 'paf', '__builtins__': <module '__builtin__' (built-in)>, '__file__': 'C:\\Python25\\Lib\\idlelib\\idle.pyw', 'idlelib': <module 'idlelib' from 'C:\Python25\lib\idlelib\__init__.pyc'>, 'diametre': 1391000, '__name__': '__main__', 'annee': 2009, '__doc__': None}

    annee = 2009
    où l'on voit que les deux items 'annee': 2009 et 'zwi':'paf' sont ajoutés à globals().

    Ce que je trouve magique là dedans c'est que créer l'item 'annee':2009 dans globals() signifie qu'on crée dans le code une variable annee en lui affectant la valeur 2009.
    C'est à dire que ce qui est une chaine dans globals() , 'annee', est le nom d'une variable, annee, dans le code.


    Le fait que ce nom ait un fonctionnement d'étiquette et qu'on l'appelle étiquette n'a pas de rapport avec le nom: ce nom s'écrit annee dans le code et 'annee' dans globals(). "Étiquette" ne signifie pas que c'est une chaine.

    Quant au nom annee, il permet dans le code d'atteindre "la valeur de la variable", c'est à dire l'objet que référence le nom de ce qu'on appelle variable. Mais le terme de variable est impropre en Python. En réalité, il y a un objet en mémoire auquel est attaché un nom comme une étiquette.
    Python a des "noms"
    http://www.biologeek.com/bonnes-prat...stuces-python/

    Comprendre ce qu'il y a dans globals(), c'est à dire des items
    'nom de variable sous forme de chaine':objet que référence la variable
    permettait de répondre en 2 secondes à la question de Zavonen.


    --------------

    Quant à la question, il fallait être au courant de ces subtilités relatives aux variables et à globals() pour s'apercevoir qu'elle pêchait en quelques endroits:
    Au lieu de
    «Je voudrais pouvoir nommer dans une boucle mes objets avec les étiquettes de la liste de chaines.»
    j'aurais préféré lire:
    «Je voudrais pouvoir référencer dans une boucle de code mes objets avec des variables dont les noms seront issus des chaines contenues dans la liste de chaines.»
    facilement traduisible en
    «Je voudrais pouvoir référencer dans globals() mes objets avec des noms de variables qui seront les chaines contenues dans la liste de chaines.»
    ce qui est ni plus ni moins que l'expression de la solution qu'il ne reste plus qu'à concrétiser en code.

    De même à la place de
    «Au lieu de référencer le premier objet par L1[0] j'aimerais le référencer par 'un'»
    il aurait dû y avoir
    «Au lieu de référencer le premier objet par L1[0] j'aimerais le référencer par un».

    C'est entendu, je suis un bleu et je me suis polarisé sur ces phrases confusionnantes alors que j'aurais dû m'attacher à comprendre
    «comme si j'avais instancié par
    un= Truc( , ..) si ma classe est Truc»

    que je ne comprenais pas.
    Mais je remarque qu'en général, les questions posées dans le forum gagneraient à être un peu peaufinées.

    C'est pour ça que je trouve que la réponse de pacificator est d'autant plus remarquable qu'il n'a pas seulement réussi à trouver la bonne réponse mais surtout à comprendre la vraie question.
    pacificator, il est fort.
    Ceci dit, pour arriver à se poser la question, il doit falloir être fort aussi. Et la mettre sur le tapis est très très instructif.
    Mais bon, «Ce qu'on trouve est plus important que ce qu'on cherche.» , je ne suis pas tellement d'accord avec ça.


    -----------------------

    Pour ce qui est de mon allusion à un dictionnaire ordonné, je crois que c'est une allusion sans rapport avec le problème.

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

Discussions similaires

  1. [XL-2003] nommer des combobox en série
    Par bosk1000 dans le forum Macros et VBA Excel
    Réponses: 6
    Dernier message: 14/09/2011, 16h21
  2. [Débutant] Nommer des objets en mouvement
    Par @@juju@@ dans le forum Images
    Réponses: 4
    Dernier message: 31/07/2007, 20h56
  3. Réponses: 6
    Dernier message: 12/02/2004, 21h55
  4. Créer des objets sur la pile ?
    Par Cornell dans le forum Langage
    Réponses: 8
    Dernier message: 03/03/2003, 11h47
  5. Importer des objets de 3dsMax
    Par Anonymous dans le forum OpenGL
    Réponses: 3
    Dernier message: 06/05/2002, 13h53

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