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 :

[string] Trier alphabetiquement des string avec des caracteres speciaux


Sujet :

Python

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé Avatar de KINENVEU
    Profil pro
    Inscrit en
    Mai 2007
    Messages
    184
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2007
    Messages : 184
    Par défaut [string] Trier alphabetiquement des string avec des caracteres speciaux
    bonjour,

    j'aimerai donc trier par ordre alphabetique des string avec des caracteres speciaux.
    du type :
    "œil", "Æ", "être", "île", "éveil", ...

    Quand je lance un "sort" brut, je n'ai pas le resultat voulu.
    (a savoir par exemple: "île" entre "hibou" et "jardin")

    j'ai essaye avec le key=str.lower(), ca me regle le probleme des capitales.
    Je n'ai pas trouve de fonction qui me transforme les caracteres speciaux en un equivalent dans [a-z].
    (par exemple: f("œil") produit "oeil", f("île") produit "ile", ...)

    quelqu'un aurait-il une idee ?

    merci par avance.

  2. #2
    Membre prolifique
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 833
    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 833
    Billets dans le blog
    1
    Par défaut
    Salut

    Tu définis ta fonction de comparaison telle que tu la veux. Elle doit
    - recevoir 2 éléments à comparer
    - renvoyer -1; 0 ou 1 selon que l'élément 1 est plus petit (selon ta propre conception de "plus petit"), égal ou plus grand que l'élément 2

    Exemple
    Code python : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    def compar(x, y):
        ... tout un code qui va gérer Æ avec le reste pour finalement
        ... renvoyer -1 ou 0 ou 1

    Ensuite, te suffit d'invoquer tableau.sort(fct) si tu veux trier ton tableau (il sera donc modifié) ou bien sorted(tableau, fct) si tu veux que le tri se fasse à la volée. Et tu peux éventuellement rajouter "reverse=True" si tu veux inverser le tri...

    Exemple
    Code python : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    tab=["œil", "Æ", "être", "île", "éveil"]
    b=sorted(tab, compar, reverse=True)
    print b
    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]

  3. #3
    Membre confirmé Avatar de KINENVEU
    Profil pro
    Inscrit en
    Mai 2007
    Messages
    184
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2007
    Messages : 184
    Par défaut
    Citation Envoyé par Sve@r Voir le message
    Salut

    Tu définis ta fonction de comparaison telle que tu la veux. Elle doit
    - recevoir 2 éléments à comparer
    - renvoyer -1; 0 ou 1 selon que l'élément 1 est plus petit (selon ta propre conception de "plus petit"), égal ou plus grand que l'élément 2
    merci.
    Mais avec cette approche,
    je vais devoir coder toutes les conversions de carateres speciaux a la main quand meme.
    Et c'est exactement ce que je voudrais eviter.

  4. #4
    Membre Expert

    Homme Profil pro
    Diverses et multiples
    Inscrit en
    Mai 2008
    Messages
    662
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Diverses et multiples

    Informations forums :
    Inscription : Mai 2008
    Messages : 662
    Par défaut
    Malheureusement, il semble ne pas y avoir de solution miracle (je trouve d’ailleurs que ça manque…). Donc, je crains qu’il ne te faille coder tes “transcriptions” à la main… Perso, je ferais comme ça*:

    * Créer une table de conversion (c’est la partie la plus pénible, python pourrait en fournir une…).
    * Trier en utilisant translate en plus de lower.

    Code python : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    >>> trans = str.maketrans({"œ":"oe", "æ":"ae", "é":"e", "è":"e","ê":"e"}) #etc.
    >>> l = ["dummy", "alors", "œuf", "advanced", "ætéria", "être", "étirer"]
    >>> l.sort(key=lambda k: k.lower().translate(trans))
    >>> l
    ['advanced', 'ætéria', 'alors', 'dummy', 'étirer', 'être', 'œuf']

  5. #5
    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,

    S'il faut faire un tri selon le dictionnaire français, il existe une solution toute faite déjà intégrée à Python et qui ne marche pas mal.

    Pour vérifier si elle marche dans tous les cas, j'ai vérifié avec cet excellent article http://www-clips.imag.fr/geta/gilles...-francais.html.

    J'ai fait quelques compléments, et j'ai fini par adopter le code suivant qui marche dans tous les cas que j'ai essayés:

    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
    import locale
     
    class Compfr(object):
     
        def __init__(self, decod='utf-8'):
            self.decod = decod
            locale.setlocale(locale.LC_ALL, '')
            self.espinsec = u'\xA0' # espace insécable
     
        def __call__(self, v1, v2):
     
            # on convertit en unicode si nécessaire
            if isinstance(v1, str):
                v1 = v1.decode(self.decod)
            if isinstance(v2, str):
                v2 = v2.decode(self.decod)
     
            # on retire les tirets et les blancs insécables
            v1 = v1.replace(u'-', u'')
            v1 = v1.replace(self.espinsec, u'')
            v2 = v2.replace(u'-', '')
            v2 = v2.replace(self.espinsec, u'')
     
            # on retourne le résultat de la comparaison
            return locale.strcoll(v1, v2)
    Voilà comment on l'utilise (ici sur un exemple de test):

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    L = ['pèche', 'PÈCHE', 'pêche', 'PÊCHE', 'péché', 'PÉCHÉ', 'pécher', 'pêcher']
    compfr = Compfr()
    L.sort(cmp=compfr)
    for mot in L:
        print mot
    pèche
    PÈCHE
    pêche
    PÊCHE
    péché
    PÉCHÉ
    pécher
    pêcher
    La liste à trier est supposée être composée de mots encodés soit en unicode, soit en utf-8. Si ce n'est pas en utf-8, on peut donner l'encodage au lancement de l'instance de classe Compfr(). De ce fait, les comparaisons sont faites en unicode.

    Si on est dans Python 3.x, l'argument cmp de la méthode sort n'existe plus. Grâce au module functools et à sa fonction cmp_to_key, on peut utiliser la même méthode de comparaison avec l'argument key de sort:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    L= [u'vicennal', u'vice-consul', u'vice-roi', u'vice-président', u'vice' +  u'\xA0' + u'versa', u'vice-versa', u'vicésimal']
     
    compfr = Compfr()
    L.sort(key=cmp_to_key(compfr))
    for mot in L:
        print mot
    vice-consul
    vicennal
    vice-président
    vice-roi
    vicésimal
    vice versa
    vice-versa
    Bien entendu, le cas des voyelles liées comme œ,Æ, ... est traité!

    Essaie pour voir si ça te convient.

  6. #6
    Membre confirmé Avatar de KINENVEU
    Profil pro
    Inscrit en
    Mai 2007
    Messages
    184
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2007
    Messages : 184
    Par défaut
    merci pour vos reponses.

    Je trouve la solution de "mont29" elegante.
    Je l'utiliserai en plan B (car je tiens a eviter de faire les conversions a la main)

    La solution de "tyrtamos" correspond tout a fait a ce que je cherche.
    Je vais la tester de ce pas et je vous tiens au courant.

    merci encore.

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

Discussions similaires

  1. Parser un JSON avec des variables avec des "-" et des ":"
    Par Quentin33 dans le forum Windows Phone
    Réponses: 2
    Dernier message: 22/05/2011, 01h04
  2. Réponses: 4
    Dernier message: 02/04/2008, 17h51
  3. function stripslashes() avec des string
    Par rigel dans le forum Langage
    Réponses: 2
    Dernier message: 04/07/2006, 08h53
  4. comment faire switch avec des strings ?
    Par ilimo dans le forum C++
    Réponses: 2
    Dernier message: 18/04/2006, 21h08
  5. petit souci avec des variables avec des fonctions psql
    Par dust62 dans le forum PostgreSQL
    Réponses: 4
    Dernier message: 02/04/2005, 13h45

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