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 dictionnaire par clés


Sujet :

Python

  1. #1
    Membre confirmé
    Profil pro
    Inscrit en
    Mars 2009
    Messages
    58
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2009
    Messages : 58
    Par défaut Tri dictionnaire par clés
    Bonjour,
    sous Python 2.5, j'ai un dictionnaire :
    >>> dico_ref
    {'r3': ['choco'], 'r1': ['fraise'], 'r2': ['vanille','choco']}
    Je voudrais trier dico_ref par ordre alpha-numérique des clés (string), ie obtenir :
    >>> {'r1': ['fraise'], 'r2': ['vanille','choco'], 'r3': ['choco']}
    J'ai essayé :
    >>> [(k,dico_ref[k]) for k in sorted(dico_ref.keys())]
    mais ça me renvoie évidemment une liste de tuples, et je perds le format dictionnaire que je veux conserver.
    Comment obtenir ce dictionnaire trié par clés ?
    Merci.

  2. #2
    Membre chevronné
    Profil pro
    Inscrit en
    Décembre 2006
    Messages
    271
    Détails du profil
    Informations personnelles :
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Décembre 2006
    Messages : 271
    Par défaut
    Attention à une chose aussi avec sorted si tu rajoutes la clé 'r10' :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    >>> s = {'r3': ['choco'], 'r1': ['fraise'], 'r2': ['vanille','choco'], 'r10': ['courgette']}
    >>> sorted(s)
    ['r1', 'r10', 'r2', 'r3']

  3. #3
    Membre confirmé
    Profil pro
    Inscrit en
    Mars 2009
    Messages
    58
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2009
    Messages : 58
    Par défaut
    Ok tamiel,
    je penserai à renommer mes clés 'r0i' si j'en ai plus de 10.
    Mais saurais-tu obtenir ce dictionnaire trié ?

  4. #4
    Expert confirmé
    Avatar de tyrtamos
    Homme Profil pro
    Retraité
    Inscrit en
    Décembre 2007
    Messages
    4 486
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2007
    Messages : 4 486
    Billets dans le blog
    6
    Par défaut
    Bonjour,

    A ma connaissance, on ne peut pas.

    Les clés du dictionnaire sont rangées en fonction de leur code hash, ce qui permet l'accès très rapide aux données, mais empêche qu'on puisse présenter le dictionnaire selon l'ordre alphanumérique des clés.

    Cependant, il faut se demander sur quel plan c'est utile.
    • Sur le plan fonctionnel, ça ne l'est pas.


    • Si on en a besoin pour l'affichage, on peut toujours le faire en transformant le dictionnaire en liste de listes, en la triant et en fabriquant une chaine de caractères qui présente ces données selon le format d'un dictionnaire.


    Tyrtamos

  5. #5
    Membre confirmé
    Profil pro
    Inscrit en
    Mars 2009
    Messages
    58
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2009
    Messages : 58
    Par défaut
    Ok, bien noté,
    j'ai fait appel à sorted(dico_ref) au lieu de dico_ref.keys() par la suite pour appeler les listes de dico_ref dans l'ordre des clés triées.
    Donc le problème est contourné.

  6. #6
    Membre émérite
    Homme Profil pro
    heu...
    Inscrit en
    Octobre 2007
    Messages
    648
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : heu...

    Informations forums :
    Inscription : Octobre 2007
    Messages : 648
    Par défaut
    Tiens, voilà une ébauche de classe, qui est donc à completer :
    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
    >>> import bisect
    >>> class SortedDico(dict):
        def __init__(self,**args):
            super(SortedDico,self).__init__()
            self.update(args)
            self._keys=list(sorted(args.keys()))
        def __setitem__(self,key,val):
            super(SortedDico,self).__setitem__(key,val)
            bisect.insort_right(self._keys,key)
        def keys(self):
            return self._keys
        def __iter__(self):
            for x in self._keys:
                yield x
        def iterItems(self):
            for x in self._keys:
                yield (x,self[x])
        def update(self,dico):
            self.update(dico)
            for key in dico:
                bisect.insort(self._keys,key)
        def remove(self,key):
            del self[key]
            self._keys.remove(key)
    Et voilà ce que ça peut donner:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    >>> a=SortedDico(name='a')
    >>> a['b']='b'
    >>> a['c']='c'
    >>> a
    {'c': 'c', 'b': 'b', 'name': 'a'}
    >>> for x in a: print x
     
    b
    c
    name

  7. #7
    Membre confirmé
    Profil pro
    Inscrit en
    Mars 2009
    Messages
    58
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2009
    Messages : 58
    Par défaut
    Merci N.Tox,
    une nouvelle classe à mon arc !
    Les dictionnaires nécessaires à mon code vont être plus lisibles.
    A +

  8. #8
    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
    Si dico_ref est un dictionnaire, sorted(dico_ref) renvoie la liste triée de ses clés.
    Ce n'est pas ce que tu semblais vouloir.
    Le type dictionnaire ordonné n'existant pas encore (il me semble avoir lu que c'est envisagé pour le futur), tu peux à défaut obtenir une liste des items du dictionnaire transformés en tuple (ou liste) triés selon les clés par

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    from operator import itemgetter
     
    dico_ref = dict(zip(('r3','r1','r2','r10'),(['choco'],['fraise'],['vanille','choco'],['courgette'])))
    print dico_ref
     
    print
    li = [tuple(u) for u in dico_ref.iteritems()]
    print li
     
    print
    li.sort(key=itemgetter(0))
    print li
    Attention, d'après ce que j'ai compris, sorted() renvoie une liste nouvellement créée , tandis que sort() trie la liste sur place donc moins de recours à la mémoire.

    De même, utiliser l'itérateur iteritems() débite les items les uns après les autres à mesure qu'ils sont nécessaires sans que soit crée préalablement une liste entière telle que le ferait items().

    Remarque au passage l'emploi de dict(zip(....)) pour créer facilement un dictionnaire à partir de deux listes, ou deux tuples.

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

Discussions similaires

  1. Copier un dictionnaire par une list comprehension
    Par Sve@r dans le forum Général Python
    Réponses: 6
    Dernier message: 12/05/2008, 10h25
  2. Réponses: 3
    Dernier message: 11/04/2008, 15h37
  3. executer une règle de tri outlook par VBA
    Par benpinta dans le forum VBA Outlook
    Réponses: 1
    Dernier message: 06/12/2007, 18h47
  4. Tri TStringList par heure
    Par rxseac dans le forum Delphi
    Réponses: 3
    Dernier message: 16/03/2007, 11h41
  5. Tri alphabétique par pertinence
    Par tim22 dans le forum Requêtes
    Réponses: 2
    Dernier message: 06/01/2007, 21h32

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