IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Voir le flux RSS

tyrtamos

[Actualité] [Python] Faire du tri selon le dictionnaire français avec sqlite3

Noter ce billet
par , 03/03/2015 à 19h18 (1575 Affichages)
Problématique

Quand on veut extraire d'une base SQL des informations texte triées en utilisant 'ORDER BY', on se heurte au problème habituel: l'ordre de tri coïncide avec l'ordre des caractères dans les polices de caractères, c'est à dire, par exemple, que:
  • 'a' est situé après 'X' (les minuscules sont situées après les majuscules),
  • 'à' est situé après 'x' (les caractères accentués sont situés après les caractères non accentués).

Solution

Pour trier selon l'alphabet français, et en fait, selon l'alphabet qu'on veut, on va créer une fonction de comparaison comme cmp(v1, v2), c'est à dire qui compare v1 et v2 et qui renvoie:
  • un entier <0 si v1<v2
  • 0 si v1==v2
  • un entier >0 si v1>v2


Ceci, comme on peut le faire avec la méthode sort() du Python.

Voilà le code proposé (Python 3):

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
import locale
 
class Compdicofr(object):
    """comparaison de 2 chaines selon le dictionnaire français"""
 
    def __init__(self):
        self.loc = locale.getlocale()  # stocke la locale courante
        self.espinsec = '\xA0'  # espace insécable
 
    def __call__(self, v1, v2):
 
        # on retire les tirets et les blancs insécables
        v1 = v1.replace('-', '')
        v1 = v1.replace(self.espinsec, '')
        v2 = v2.replace('-', '')
        v2 = v2.replace(self.espinsec, '')
 
        # on fait la comparaison selon la locale
        locale.setlocale(locale.LC_ALL, '')
        comp = locale.strcoll(v1, v2)
 
        # retour à la locale initiale
        locale.setlocale(locale.LC_ALL, self.loc)
 
        # on retourne le résultat de la comparaison
        return comp
 
compdicofr = Compdicofr()

Prenons maintenant un exemple: on crée une base sqlite3 contenant une table "test" avec un champ "mots" contenant dans l'ordre d'introduction:


Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
xabc
abcç
abcé
Xabcù
Abcè
êqsdf
Voilà le code pour extraire ces données et les présenter dans l'ordre de tri habituel:


Code PYTHON : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
cur.execute("""
    SELECT *
    FROM test 
    ORDER BY mots
    """)
datas = cur.fetchall()
 
for data in datas:
    print data[0]

Ce qui donne à l'exécution:


Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
Abcè
Xabcù
abcç
abcé
xabc
êqsdf
Vous constatez que ce n'est pas terrible: le 'a' est après le 'X' et le 'ê' est après le 'x'...

Voilà maintenant le code qui permet de trier dans le bon ordre:

Code PYTHON : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
cnx.create_collation("compdicofr", compdicofr)
 
cur.execute("""
    SELECT *
    FROM test 
    ORDER BY mots COLLATE compdicofr
    """)
datas = cur.fetchall()
 
for data in datas:
    print data[0]

Ce qui affiche:

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
abcç
abcé
Abcè
êqsdf
xabc
Xabcù
C'est quand même autre chose, non?

Envoyer le billet « [Python] Faire du tri selon le dictionnaire français avec sqlite3 » dans le blog Viadeo Envoyer le billet « [Python] Faire du tri selon le dictionnaire français avec sqlite3 » dans le blog Twitter Envoyer le billet « [Python] Faire du tri selon le dictionnaire français avec sqlite3 » dans le blog Google Envoyer le billet « [Python] Faire du tri selon le dictionnaire français avec sqlite3 » dans le blog Facebook Envoyer le billet « [Python] Faire du tri selon le dictionnaire français avec sqlite3 » dans le blog Digg Envoyer le billet « [Python] Faire du tri selon le dictionnaire français avec sqlite3 » dans le blog Delicious Envoyer le billet « [Python] Faire du tri selon le dictionnaire français avec sqlite3 » dans le blog MySpace Envoyer le billet « [Python] Faire du tri selon le dictionnaire français avec sqlite3 » dans le blog Yahoo

Mis à jour 04/03/2015 à 07h44 par tyrtamos

Catégories
Python , Programmation , Python

Commentaires

  1. Avatar de mproy
    • |
    • permalink
    Cela permet d'éviter de recourir à une colonne de tri, c'est-à-dire une colonne contenant une version modifiée d'une autre colonne et sur laquelle on va faire le tri (ex., Jean-Gaël -->JEANGAEL, ...).

    Pour plus de renseignement sur l'utilisation de COLLATE, je suggère : https://wellsr.com/python/making-new...ate_collation/.