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 :

Tri d'un dictionnaire


Sujet :

Python

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Femme Profil pro
    Étudiant
    Inscrit en
    Octobre 2019
    Messages
    42
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 45
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Octobre 2019
    Messages : 42
    Par défaut Tri d'un dictionnaire
    Hello,

    Je souhaite pouvoir facilement trier un dictionnaire. En l'état j'utilise "sorted" avec un paramètre et j'applique une mise en forme comme ceci (cf partie en gras):

    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
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    #Déclaration des fonctions
    def somme(list_of_name, key):
        som=sum([seq[name][key] for name in list_of_name])
        return som
    
    def comb(m, lst):
        if m == 0: return [[]]
        return [[x] + suffix for i, x in enumerate(lst)
                for suffix in comb(m - 1, lst[i + 1:])]
     
    # Déclaration des valeurs de reliques et de la base
    Relique1= {'Santé':5,'Degats':6,'Armure':2,'Perforation':7,'Critique':2,
               }
    Relique2= {'Santé':10,'Degats':9,'Armure':3,'Perforation':1,'Critique':4,
               }
    Relique3= {'Santé':7,'Degats':17,'Armure':4,'Perforation':6,'Critique':6,
               }
    
    
    Base= {'Santé':0,'Degats':0,'Armure':0,'Perforation':0,'Critique':0,
               }
    
    seq={"Relique1":Relique1, "Relique2":Relique2,"Relique3":Relique3}
    
    for i in seq:
     names=list(seq) 
    
    #Calcul des combinaisons possibes
    combinaisons = comb(2, names)
    
    #calcul des valeurs des différentes combinaisons de reliques
    totaux = { key: [ somme(c,key) for c in combinaisons ] for key in ("Santé","Degats","Armure","Perforation","Critique",
                                                                       ) }
    
    #Ajout des valeurs de la Base aux résultats des combinaisons de reliques
    final={}
    for cle,valeurT in totaux.items():
        newval=[]
        for val in valeurT:
            newval.append(val + Base.get(cle))
            intermediaire={cle:newval}
        final.update(intermediaire)
    
    #Triage des résultats en fonction des combinaisons    
    resultat=sorted(zip( final.get("Santé"),final.get("Degats"),final.get("Armure"),final.get("Perforation"),final.get("Critique"),combinaisons) ,reverse=True)
    
    #Mise en forme finale
    for TS, TD, TA, TP, TC, v in resultat:
        print('*******************',)
        print("La combinaison",v,'\n',)
        print("Santé=",TS,'\n',"Degats=",TD,'\n',"Armure=",TA,'\n',"Perforation=",TP,'\n',"Critique=",TC,'\n',)
    Ca fonctionne comme je souhaite. Les résultats sont bien triés par ordre décroissant en fonction des valeurs du paramètre "Santé".
    Maintenant si je veux changer le tri des résultats en fonction par exemple de "Perforation". Je dois modifier le "sorted" pour lui mettre en paramètre "Perforation" et modifier la mise en forme finale. Un peu lourd...

    Comment pourrais je faire pour que cela soit plus souple à trier sans tout changer chaque fois?

    Merci d'avance.

  2. #2
    Membre Expert

    Homme Profil pro
    Ingénieur calcul scientifique
    Inscrit en
    Mars 2013
    Messages
    1 229
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Ingénieur calcul scientifique

    Informations forums :
    Inscription : Mars 2013
    Messages : 1 229
    Par défaut
    Qu'est ce qui est lourd ? Lourd pour vous lorsque vous devez modifier le sorted à chaque fois ou bien lourd pour votre ordinateur de modifier toutes ces mises en formes ?

    S'il s'agit du second point, je pense pas que ce soit si lourd pour votre machine, vu ce que vous manipulez, et je ne penses pas que vous ayez trop le choix.
    Pour le premier point vous pouvez englober votre sorted dans une fonction, dont l'interface sera plus simple pour l'utilisateur, et qui fera elle l'appel au sorted.

    Je n'ai pas testé, mais vous devriez trouver votre bonheur avec qqch comme ça :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    def tri(final, combinaisons, key_list):
           finalgetters = tuple( final.get(key) for key in key_list )
           return sorted(zip( *finalgetters ,combinaisons) ,reverse=True)
     
    res = tri(final, combinaisons, ["Santé","Degats","Armure","Perforation","Critique"])

  3. #3
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 832
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 832
    Billets dans le blog
    1
    Par défaut
    Bonjour

    Perso j'ai eu un peu de mal à comprendre ton code et quelque chose me dit qu'à mon avis, tu devrais revoir les bases dès à présent parce qu'il n'est pas super évolutif. Par exemple pour comprendre ce qu'il faisait j'ai voulu rajouter Relique4= {'Santé':2,'Degats':12,'Armure':5,'Perforation':8,'Critique':1, } mais j'ai dû rajouter aussi "Relique4": Relique4 dans seq.
    Alors que tu aurais écrit "Relique" de cette façon...
    Code python : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    Relique=(
    	{'Santé':5,'Degats':6,'Armure':2,'Perforation':7,'Critique':2, },
    	{'Santé':10,'Degats':9,'Armure':3,'Perforation':1,'Critique':4, },
    	{'Santé':7,'Degats':17,'Armure':4,'Perforation':6,'Critique':6, },
    	{'Santé':2,'Degats':12,'Armure':5,'Perforation':8,'Critique':1, },
    )
    ... tu n'aurais plus besoin de "seq". Et si vraiment il te faut un nom, alors
    Code python : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    Relique=(
    	{"nom" : "Relique1", "values" : {'Santé':5,'Degats':6,'Armure':2,'Perforation':7,'Critique':2, }},
    	{"nom" : "Relique2", "values" : {'Santé':10,'Degats':9,'Armure':3,'Perforation':1,'Critique':4, }},
    	{"nom" : "Relique3", "values" : {'Santé':7,'Degats':17,'Armure':4,'Perforation':6,'Critique':6, }},
    	{"nom" : "Relique4", "values" : {'Santé':2,'Degats':12,'Armure':5,'Perforation':8,'Critique':1, }},
    )

    Bref des fondations bien solides permettent ensuite une évolution plus aisée.

    Sinon pour ta question j'ai pas vraiment de solution magique. Peut-être une fonction à laquelle tu passerais l'ordre des éléments (ex affich("Santé", "degats", "Armure", "Perforation", "Critique") et elle se chargerait alors de gérer le tri et l'affichage selon les demandes (ps: tu peux très-bien définir ta fonction ainsi: def affich(*args) ce qui te permet de ne pas te préoccuper du nombre d'éléments quand tu l'appelles).
    Ou alors passer carrément à l'objet...
    Code python : 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
    class cRelique:
    	def __init__(self, name="base", sante=0, degat=0, armure=0, perforation=0, critique=0):
    		self.__name=name
    		self.__sante=sante
    		self.__degat=degat
    		self.__armure=armure
    		self.__perforation=perforation
    		self.__critique=critique
    	# __init__()
    # class cRelique
     
    Relique=(
    	cRelique("Relique1", 5, 6, 2, 7, 2),
    	cRelique("Relique2", 10, 9, 3, 1, 4),
    	cRelique("Relique3", 7, 17, 4, 6, 6),
    	cRelique("Relique4", 2, 12, 5, 8, 1),
    )
     
    base=cRelique()
    ... ce qui te permettrait alors d'y rajouter diverses méthodes spécifiques pour son tri et/ou son affichage...

    Sinon j'ai bien aimé la fonction "combinaison()". C'est justement pour tester si comb(3, names) fonctionnait que j'ai rajouté cette 4° relique...

    Citation Envoyé par lg_53 Voir le message
    Qu'est ce qui est lourd ? Lourd pour vous lorsque vous devez modifier le sorted à chaque fois ou bien lourd pour votre ordinateur de modifier toutes ces mises en formes ?
    Moi je l'ai compris "lourd pour le programmeur". C'est vrai que si on veut changer le critère de tri, faut modifier le sorted() et (comme on veut probablement ce critère en premier à l'affichage) faut modifier l'affichage...
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

  4. #4
    Membre averti
    Femme Profil pro
    Étudiant
    Inscrit en
    Octobre 2019
    Messages
    42
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 45
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Octobre 2019
    Messages : 42
    Par défaut
    Merci beaucoup Sve@r et lg_53
    Quand je dis lourd c'est dans le sens ou il faut que je modifie le tri et l'affichage des résultats en fonction de ce que je souhaite comme paramètre de tri.
    j'essaye de comprendre tout ca et je reviens vers vous

  5. #5
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 832
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 832
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par DantonLuc Voir le message
    j'essaye de comprendre tout ca et je reviens vers vous
    Essaye plutôt de regarder (et comprendre) ça. Ce truc me plaisait et je l'ai fait. Et je l'ai fait en 100% objet.

    Code python : 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
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    #!/usr/bin/env python3
    # coding: utf-8
     
    class cRelique:
    	__carac=("sante", "degat", "armure", "perforation", "critique")
    	def __init__(self, name="", sante=0, degat=0, armure=0, perforation=0, critique=0):
    		self.__values={
    			"name" : name,
    		}
    		self.__values.update(
    			zip(
    				cRelique.__carac,
    				(sante, degat, armure, perforation, critique),
    			)
    		)
    	# __init__()
     
    	# Pour pouvoir utiliser l'objet comme un dictionnaire
    	__getitem__=lambda self, k: self.__values[k]
     
    	# La liste des combinaisons d'objets
            @staticmethod
    	def comb(n, reliques):
    		# Fonction récursive de génération
    		def generate_r(n, lst):
    			if n == 0: return ((),)
    			return (
    				(x,) + suffix
    				for (i, x) in enumerate(lst)
    				for suffix in generate_r(n-1, lst[i+1:])
    			)
    		# generate_r()
     
    		# Génération des reliques
    		return tuple(generate_r(n, reliques))
    	# comb()
     
    	# Les totaux des valeurs des combinaisons
            @staticmethod
    	def totaux(reliques, comb, base=None):
    		tot={}
    		for c in comb:
    			tot[c]={}
    			for k in cRelique.__carac:
    				tot[c][k]=sum(x[k] for x in reliques if x in c)
    				if base: tot[c][k]+=base[k]
    		# for
    		return tot
    	# totaux()
     
    	# La même mais en plus fun
    	totaux2=staticmethod(
    		lambda reliques, comb, base=None: {
    			c : {
    				k : sum(x[k] for x in reliques if x in c) + base[k] if base else 0
    				for k in cRelique.__carac
    			} for c in comb
    		}
    	)
     
    	# Le tri des totaux
            @staticmethod
    	def sort(tableau, k, reverse=False):
    		return sorted(tableau, key=lambda x:x[1][k], reverse=reverse)
     
    	# La même mais en utilisant une lambda
    	sort2=staticmethod(
    		lambda tableau, k, reverse=False: sorted(tableau, key=lambda x:x[1][k], reverse=reverse)
    	)
    # class cRelique
     
    Relique=(
    	cRelique("Relique1", 5, 6, 2, 7, 2),
    	cRelique("Relique2", 10, 9, 3, 1, 4),
    	cRelique("Relique3", 7, 17, 4, 6, 6),
    	cRelique("Relique4", 2, 12, 5, 8, 1),
    )
     
    Base=cRelique()
     
    # Calcul des combinaisons possibes
    combinaisons=cRelique.comb(2, Relique)
    print("comb: ", tuple(tuple(r["name"] for r in c) for c in combinaisons))
     
    # Les totaux des valeurs des combinaisons
    totaux=cRelique.totaux(Relique, combinaisons, Base)
    print("totaux")
    for (k, v) in totaux.items():
    	print(tuple(x["name"] for x in k), v)
     
    # Le tri des totaux
    tri=cRelique.sort(totaux.items(), "armure", reverse=True)
    print("tri")
    for t in tri:
    	print(tuple(x["name"] for x in t[0]), t[1])

    La grosse différence, c'est que moi pour les combinaisons j'ai directement stocké les objets au lieu de leur nom. Exemple toi tu générais (par exemple) ("Relique1, "Relique2") moi je génère (objet1, objet2). Après-tout, stocker le nom d'un objet ou stocker l'objet lui-même (plus concrètement son adresse) ça ne change rien à l'algo (si tu veux ensuite le nom te suffit de demander for x in genere(): print(x["name"]) comme dans mon exemple où j'affiche les objets combinés). Pour le reste c'est pareil hormis que le tri, lui, est maintenant devenu complètement paramétrable. Dans mon exemple je trie sur "armure" mais rien ne t'interdit de trier sur "sante" ou "degat".

    Ne reste qu'à faire l'affichage mais je pense que là tu peux t'en sortir (créer une méthode statique ressemblant à "totaux" et prenant en paramètre les caractéristiques à afficher...)
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

  6. #6
    Membre averti
    Femme Profil pro
    Étudiant
    Inscrit en
    Octobre 2019
    Messages
    42
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 45
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Octobre 2019
    Messages : 42
    Par défaut
    Effectivement en objets ca parait mieux!
    Un petit truc rapide à te demander avant que je regarde en détails, l'affichage du tri n'est pas inversé.
    Je voudrais que le tri m'affiche en premier les plus fortes valeurs. Dans la fonction "sort que tu as créé, il y a bien un reverse mais si je le mets à True cela ne change rien.

  7. #7
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 832
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 832
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par DantonLuc Voir le message
    Effectivement en objets ca parait mieux!
    Je veux que c'est mieux
    L'objet intègre à la fois les datas et les outils pour les manipuler. Une fois bien construit, un objet c'est 1000 fois plus souple à utiliser que quand on a les datas d'un côté et les fonctions de l'autre (dans ton code tu avais "seq", "names", et "somme()" qui étaient certes utiles mais qui pourrissaient un peu la compréhension).
    Mais l'objet faut se le construire d'abord...

    Citation Envoyé par DantonLuc Voir le message
    Un petit truc rapide à te demander avant que je regarde en détails, l'affichage du tri n'est pas inversé.
    J'avais oublié de reporter le paramètre "reverse" dans le tri. C'est rectifié.
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

  8. #8
    Rédacteur

    Avatar de danielhagnoul
    Homme Profil pro
    Étudiant perpétuel
    Inscrit en
    Février 2009
    Messages
    6 389
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 74
    Localisation : Belgique

    Informations professionnelles :
    Activité : Étudiant perpétuel
    Secteur : Enseignement

    Informations forums :
    Inscription : Février 2009
    Messages : 6 389
    Billets dans le blog
    125
    Par défaut


    Je suis encore loin du niveau de Sve@r, je n'ai pas encore sérieusement tâté de la POO en Python, mais voilà à quoi je viens d'arriver :

    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
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    #! python3
    # coding: utf-8
     
    from termcolor import cprint
    from itertools import combinations
     
    """Combinaisons et tri de dict"""
     
    reliques = (
        {'Santé': 5, 'Degats': 6, 'Armure': 2, 'Perforation': 7, 'Critique': 2, },
        {'Santé': 10, 'Degats': 9, 'Armure': 3, 'Perforation': 1, 'Critique': 4, },
        {'Santé': 7, 'Degats': 17, 'Armure': 4, 'Perforation': 6, 'Critique': 6, },
        {'Santé': 2, 'Degats': 12, 'Armure': 5, 'Perforation': 8, 'Critique': 1, },
    )
     
    combinaisons = list(combinations([x for x in range(len(reliques))], 2))
     
    # print(combinaisons)
     
     
    def somme(lst, key):
        return sum([reliques[n][key] for n in lst])
     
     
    totaux = {key: [somme(c, key) for c in combinaisons]
              for key in tuple(reliques[0].keys())}
     
    # print(totaux)
     
     
    def presentation(lst):
        def tri(final, combinaisons, key_list):
            finalgetters = tuple(final.get(key) for key in key_list)
            return sorted(zip(*finalgetters, combinaisons), reverse=True)
     
        res = tri(totaux, combinaisons, lst)
     
        # print(res)
     
        for item in res:
            cprint('*******************', 'white')
            cprint("La combinaison {}".format(item[5]), "blue")
            cprint('''{} = {}, {} = {}, {} = {}, {} = {}, {} = {}'''.format(
                lst[0], item[0], lst[1], item[1], lst[2], item[2], lst[3], item[3], lst[4], item[4]), 'green')
     
     
    presentation(["Santé", "Degats", "Armure", "Perforation", "Critique"])
     
    """
    On peut trier dans un ordre différent, par exemple : 
    ["Degats", "Armure", "Perforation", "Critique", "Santé"]
    """

    Blog

    Sans l'analyse et la conception, la programmation est l'art d'ajouter des bogues à un fichier texte vide.
    (Louis Srygley : Without requirements or design, programming is the art of adding bugs to an empty text file.)

  9. #9
    Membre averti
    Femme Profil pro
    Étudiant
    Inscrit en
    Octobre 2019
    Messages
    42
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 45
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Octobre 2019
    Messages : 42
    Par défaut
    Merci danielhagnoul mais j'obtiens cette erreur ModuleNotFoundError: No module named 'termcolor'
    J'ai la version python 3.7.3 et je n'ai jamais ajouter de module...

    Je me concentre pour le moment sur celui de Sve@r et la mise en fome des résultats, pour passer de:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    ('Relique1', 'Relique2') {'sante': 16, 'degat': 16, 'armure': 6, 'perforation': 9, 'critique': 6}
    A cela
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    *******************
    Relique1, Relique2
    sante: 16
    degat: 16
    armure: 6
    perforation: 9
    critique: 6
    Et j'en suis que là...
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    print("tri")
    for t in tri:
    	print('*******************',)
    	print(tuple(x["name"] for x in t[0]))
    Je lis la doc sur les tuples pour mieux comprendre

  10. #10
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 832
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 832
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par danielhagnoul Voir le message
    Je suis encore loin du niveau de Sve@r
    Sympa
    Et encore j'ai du bol, wiztricks n'est pas venu rajouter son grain de sel. Lui il réécrit tout mon code en 3 lignes à base de collections dans tous les sens et il rajoute "et si on veut on peut optimiser encore un peu"

    Ceci dit, tu as moins de posts que moi mais plus de points (donc tes posts sont sensiblement mieux appréciés).

    Citation Envoyé par danielhagnoul Voir le message
    , je n'ai pas encore sérieusement tâté de la POO en Python
    Tu devrais. C'est trop puissant quand tu commences à comprendre les principes...

    Citation Envoyé par DantonLuc Voir le message
    Je me concentre pour le moment sur celui de Sve@r et la mise en fome des résultats
    Pas compliqué. Juste ce qu'il faut que tu comprennes, c'est que tel que j'ai programmé la combinaison et le tri, tu auras au final un tableau de tuples. Et chaque tuple contiendra 2 éléments
    • un tuple contenant les objets combinés (ex (relique1, relique2) => donc oui le premier élément du tuple est lui-même un tuple (et pas forcément de 2 éléments car ça dépend de la combinaison demandée)
    • un dictionnaire contenant les caractéristiques et leur somme

    Donc (résumé) chaque élément du tableau trié sera de ce type: ((reliqueX, reliqueY), {"sante" : n, "degat" : n, "armure" : n, "perforation" : n, "critique" : n}).

    Donc suffit d'afficher les objets de tab[0] d'un côté ; puis tab[1] ligne à ligne de l'autre (tab étant lui-même issu d'une boucle sur tri). Ce qui donne par exemple un truc de ce genre
    Code python : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    	# L'affichage
            @staticmethod
    	def affich(tableau, *args):
    		for t in tableau:
    			print("*" * 50)
    			print(tuple(x["name"] for x in t[0]))		# Les noms des objets combinés
    			for k in (x for x in args if x in cRelique.__carac):
    				print("%s: %d" % (k, t[1][k]))
    		# for
    	# affich()
    A rajouter dans l'objet (par exemple sous "sort2")...

    Et son utilisation
    Code python : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    # Le tri des totaux
    tri=cRelique.sort(totaux.items(), "armure", reverse=True)
    print("tri")
    cRelique.affich(tri, "armure", "degat", "sante", "perforation")

    Citation Envoyé par DantonLuc Voir le message
    Je lis la doc sur les tuples pour mieux comprendre
    Oh pour ça faut pas te faire mal au crane. Si tu connais les listes alors tu n'as qu'à te dire qu'un tuple c'est une liste non modifiable. Dans ton premier code tu renvoies des listes dans tous les sens mais perso, quand j'ai pas besoin de modifier les valeurs d'un tableau alors je le mets en tuple. Typiquement te suffit de remplacer [...] par tuple((...)) et ça marche pareil (mais c'est moins lourd évidemment puisqu'un tuple n'intègre pas les méthodes de modification qu'on trouve dans une liste).
    Toutefois dans les listes en intension, un truc de ce genre [x for x in iterable] (qui est donc au final une liste) doit, si on veut avoir un tuple, être remplacé par tuple(x for x in iterable) pour avoir un tuple à la place (le mot "tuple" doit être expressément demandé).
    Par exemple dans l'affichage j'écris ceci: print(tuple(x["name"] for x in t[0])) # Les noms des objets combinés mais si j'avais voulu afficher une liste, j'aurais pu écrire ceci print(list(x["name"] for x in t[0])) ou plus simplement cela print([x["name"] for x in t[0]]).
    Mais si j'écris ceci : print((x["name"] for x in t[0])) là ça ne marche plus parce que (...) est un générateur et que si on veut un tuple il faut le demander expressément.

    Bon évidemment quand on génère des tuples de façon récursive (comme dans "generate_r") faut super faire gaffe car si on rate un "tuple()" on se retrouve avec un générateur à l'arrivée et un générateur n'est pas indicable (interdit d'écrire truc[x] si "truc" est un générateur). A ce propos j'ai corrigé mon code précédent car (x, ) + tuple(suffix,) était inutile (en transformant le résultat du générateur en tuple tout à la fin, (x, ) + suffix suffit).

    Dernier détail: pour une liste ce sont les crochets qui font la liste (ex [1, 2, 3]) tandis que pour un tuple c'est la virgule (ex 1, 2, 3). Toutefois je mets toujours des parenthèses (d'une part pour des questions de lisibilité et d'autre part elles sont parfois nécessaires donc en les mettant tout le temps je me casse pas le luc). Mais pour une liste à un élément la virgule n'est pas obligatoire (ex [1]) tandis qu'elle l'est pour un tuple (ex (1,)). D'où le (x,) dans la fonction de génération. Et en mettant aussi la virgule pour la liste à un élément là non plus ça mange pas de pain (ex [1,]).
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

  11. #11
    Membre averti
    Femme Profil pro
    Étudiant
    Inscrit en
    Octobre 2019
    Messages
    42
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 45
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Octobre 2019
    Messages : 42
    Par défaut
    Merveilleux merci!

    Et our ne pas pas à avoir à modifier le code chaque fois que je change le paramètre de tri, j'ai rajouté ca
    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
    20
    21
    22
    23
     
    raw_input = input
     
    #Choix du paramètre
    print("1.Santé","2.Dégats", "3.Armure", "4.Perforation", "5.Critique")
     
    while 1:
        reponse = raw_input("Choisissez un paramètre de tri: ")
        if reponse in ['1','2','3','4','5']:
            if reponse == '1':
                choix = "sante"
            elif reponse == '2':
                choix = "degat"
            elif reponse == '3':
                choix = "armure"
            elif reponse == '4':
                choix = "perforation"
            elif reponse == '5':
                choix = "critique"
            break
        else:
            print ("Choix incorrect !")
    print(choix)
    Que j'injecte dans les paramètres de tri.

    Très content! Merci

  12. #12
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 832
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 832
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par DantonLuc Voir le message
    while 1
    Laisse-moi deviner: tu as fait du C avant non ??? while True.

    Citation Envoyé par DantonLuc Voir le message
    if reponse in ['1','2','3','4','5']
    Qu'est-ce que t'as pas compris sur l'avantage à utiliser des tuples par rapport aux listes ??? if reponse in ('1','2','3','4','5'). Et si on est certain qu'on n'aura que des nombres à un chiffre => if reponse in "12345".

    Maintenant on peut supprimer tous ces "if/elif" et faire ça de façon plus "python" (en n'oubliant pas que les caractéristiques sont déjà écrites dans l'objet)
    Code python : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    #Choix du paramètre
    print(" ".join("%d.%s" % (i, c) for (i, c) in enumerate(cRelique.carac, 1)))
     
    while True:
    	reponse = raw_input("Choisissez un paramètre de tri: ")
    	choix=dict((str(i), c) for (i, c) in enumerate(cRelique.carac, 1)).get(reponse)
    	if choix is not None: break
    	print ("Choix incorrect !")
    # while
    print(choix)
    (mais dans le code d'origine il faut remplacer "__carac" par "carac" => inconvénient quand un élément privé devient public).

    Citation Envoyé par DantonLuc Voir le message
    Que j'injecte dans les paramètres de tri.
    C'est ça la force de l'objet. Bien conçu, on peut l'utiliser de diverses façons dans diverses situations.
    Mon Tutoriel sur la programmation «Python»
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site
    Et on poste ses codes entre balises [code] et [/code]

Discussions similaires

  1. [Python 2.X] tri d'un dictionnaire de dictionnaire
    Par DonKnacki dans le forum Général Python
    Réponses: 4
    Dernier message: 04/09/2018, 13h58
  2. [XL-2003] Tri - double d'un dictionnaire
    Par MarcelG dans le forum Macros et VBA Excel
    Réponses: 3
    Dernier message: 14/08/2012, 10h17
  3. [Débutant] C# tri d'un dictionnaire
    Par JonathanMQ dans le forum C#
    Réponses: 7
    Dernier message: 14/07/2012, 02h49
  4. Tri dictionnaire par clés
    Par mister2502 dans le forum Général Python
    Réponses: 7
    Dernier message: 07/04/2009, 21h37
  5. Tri liste dans un dictionnaire
    Par MC wacko dans le forum Général Python
    Réponses: 5
    Dernier message: 21/01/2008, 14h20

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