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 :

Opération sur une chaine


Sujet :

Python

  1. #1
    Futur Membre du Club
    Profil pro
    Inscrit en
    Décembre 2008
    Messages
    13
    Détails du profil
    Informations personnelles :
    Âge : 38
    Localisation : France, Gironde (Aquitaine)

    Informations forums :
    Inscription : Décembre 2008
    Messages : 13
    Points : 5
    Points
    5
    Par défaut Opération sur une chaine
    Bonsoir à tous,

    Je planche actuellement sur une fonction qui me permettrait de supprimer certaines voyelles (et semi voyelles ou consonnes muettes) d'une chaine de caractères, puis de convertir les lettres restantes en chiffres (mais ce n'est pas pour tout de suite ).


    Voici ma fonction et mon problème :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    def voyelles(chaine):
    bib1=["AEIOUYWH"]
    bib2=[""]
    i=0
    for mot in bib1:
    repl=bib2[i]
    for lettre in mot:
    chaine=chaine.replace(lettre,repl)
    i+=1
    return chaine
    J'aimerais faire en sorte que la fonction ignore la première lettre de la chaine et la conserve même si c'est une voyelle mais je sèche...

    J'ai essayé plusieurs choses, je ne sais pas trop si je dois rajouter une condition ou un while.

    J'ai tenté aussi de rajouter par exemple un for lettre in mot[1:]:

    Ça marche et garde le second caractère même si c'est une voyelle, mais si j'essaie [0:] (pour faire à partir du second caractère et laisser le premier de coté) cela ne fonctionne plus et j'ai du mal à saisir pourquoi.

    Je dois être un peu fatiguée, je sais que tout cela est simpliste mais je vous remercie par avance pour votre aide.



  2. #2
    Membre extrêmement actif
    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
    Points : 1 658
    Points
    1 658
    Par défaut
    Ta fonction est manifestement destinée à évoluer en recevant des éléments supplémentaires dans bib1 et bib2.
    C'est pourquoi j'augmente artificiellement leur contenu pour réfléchir plus aisément:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
        bib1=["AEI","OU","YWH"]
        bib2=["","",""]
    Ceci permet de se rendre compte que l'état actuel de ta fonction dans lequel les listes bib1 et bib2 comptent chacune 1 seul élément trouble la vision de ce qu'il y a à faire et que cela ne t'a pas permis de t'apercevoir que , non, ta fonction ne marche pas: en réalité, elle n'itère pas.
    Si elle tourne, c'est uniquement parce qu'il n'y a qu'un seul élément dans bib1 et dans bib2.

    Avant de penser à ton problème de [1:] ,il faut donc faire en sorte que la fonction marche vraiment.

    Le trouble provient du fait que tu as besoin d'utiliser successivement des couples (el1,el2) dans lesquels el1 est de bib1 et el2 de bib2 et que tu penses l'itération à la fois comme un parcours de bib1 par éléments (for mot in bib1) et comme un parcours de bib2 par indice (le i de bib2[i]) . Mais évidemment el1 et el2 étant en correspondance, il n'est pas possible de faire ce qui est en réalité une seule itération en utilisant deux moyens. Il te faut donc choisir:

    - soit itérer selon les éléments de bib1, mais ça donne quelque chose d'inutilement compliqué:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    ch = 'BEFORE THE END OF THE DAY, THE CAT WAS DEAD'
     
    def voyelles(chaine):
        bib1=["AEI","OU","YWH"]
        bib2=["","",""]
        for mot in bib1:
            i = bib1.index(mot)
            repl=bib2[i]
            for lettre in mot:
                chaine=chaine[0] + chaine[1:].replace(lettre,repl)
        return chaine
     
    print ch
    print voyelles(ch)
    - soit itérer selon un indice jouant un rôle commun dans les deux listes:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    ch = 'BEFORE THE END OF THE DAY, THE CAT WAS DEAD'
     
    def voyelles(chaine):
        bib1=["AEI","OU","YWH"]
        bib2=["","",""]
        for i in xrange(0,len(bib1)):
            mot,repl = bib1[i],bib2[i]
            for lettre in mot:
                chaine=chaine[0] + chaine[1:].replace
        return chaine
     
    print ch
    print voyelles(ch)

    J'ai aussi pensé à un autre algorithme:
    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
    def voy(chaine):
        bib1=["AEI","OU","YWH"]
        bib2=["","",""]
        out = chaine[0]
        for i in xrange(0,len(bib1)):
            mot,repl = bib1[i],bib2[i]
            for caractere in chaine[1:]:
                if caractere in mot:
                    out += repl
                else:
                    out += car
        return chaine
     
    print ch
    print voyelles(ch)
    qui peut se simplifier en
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    def voy(chaine):
        bib1=["AEI","OU","YWH"]
        bib2=["","",""]
        out = chaine[0]
        for i in xrange(0,len(bib1)):
            for caractere in chaine[1:]:
                if caractere in bib1[i]:
                    out += bib2[i]
                else:
                    out += car
        return chaine
    Il y a plein d'autres algorithmes envisageables. Mais pour rester sur le tien, je pense que tu as tout avantage à utiliser un dictionnaire au lieu de deux listes:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    ch = 'BEFORE THE END OF THE DAY, THE CAT WAS DEAD'
     
    def voyelles(chaine):
        repl = {"AEI":"","OU":"","YWH":""}
        for mot in repl:
            for lettre in mot:
                chaine=chaine[0] + chaine[1:].replace(lettre,repl[mot])
        return chaine
     
    print ch
    print voyelles(ch)
    -------------------------

    En fait, concernant l'algorithme, étant donné ce que tu souhaite comme développement ultérieur, je pense que LA solution est d'utiliser translate().
    Il se trouve que quelqu'un a demandé des renseignements sur cette fonction il y a 4 jours:
    http://www.developpez.net/forums/d69...nne-translate/

  3. #3
    Membre expérimenté
    Homme Profil pro
    Inscrit en
    Mars 2007
    Messages
    941
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations forums :
    Inscription : Mars 2007
    Messages : 941
    Points : 1 384
    Points
    1 384
    Par défaut
    Juste une petite addition. Au lieu de:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    for i in xrange(0,len(bib1)):
        mot,repl = bib1[i],bib2[i]
        ...
    La fonction zip est là pour ça:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    for mot, repl in zip(bib1,bib2):
        ...
    Ici, "zip" est sans doute plus adapté, mais je signale aussi la fonction enumerate:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    for i, mot in enumerate(bib1):
        repl = bib2[i]
        ...

  4. #4
    Futur Membre du Club
    Profil pro
    Inscrit en
    Décembre 2008
    Messages
    13
    Détails du profil
    Informations personnelles :
    Âge : 38
    Localisation : France, Gironde (Aquitaine)

    Informations forums :
    Inscription : Décembre 2008
    Messages : 13
    Points : 5
    Points
    5
    Par défaut
    Bonsoir à tous =)

    Merci pour vos réponses !
    J'ai finalement choisi le dictionnaire comme montrait Eyquem.

    Pour ma première fonction, tu disais qu'elle fonctionnait uniquement car il n'y avait un seul élément dans les listes, mais je l'utilisais également pour le codage en chiffre ou la suppression des accents avec plusieurs éléments (voir dans le script plus bas) et j'avais l'impression qu'elle marchait pourtant selon les tests que j'ai pu faire.
    Ce n'était qu'une impression ?

    La version définitive de la chose qui est un petit Soundex simplifié :

    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
    def soundex(chaine):
    # Remplacement des caractères accentués et suppression des espaces éventuels
        repl = {"âäà":"a","éèêë":"e","îï":"i","ôö":"o","ûùü":"u","ç":"c"," ":""}
        for mot in repl:
            for lettre in mot:
                chaine=chaine[0]+chaine[1:].replace(lettre,repl[mot])
        chaine=chaine.upper()       #Passage en majuscule
    #Suppression des voyelles, w et h, en gardant la première lettre
        repl = {"AEI":"","OU":"","YWH":""}
        for mot in repl:
            for lettre in mot:
                chaine=chaine[0]+chaine[1:].replace(lettre,repl[mot])
    #Remplacement des lettres restantes par le code associé
        repl = {"BP":"1","CKQ":"2","DT":"3","L":"4","MN":"5","R":"6","GJ":"7","XZS":"8","FV":"9"}
        for mot in repl:
            for lettre in mot:
                chaine=chaine[0]+chaine[1:].replace(lettre,repl[mot])
    #Suppression des doublons
        chaine2=chaine[0]
        for n in chaine[1:]:
            if chaine2[-1] != n:
                chaine2 += n
    #Mise en forme du code sous forme Lettre chiffre chiffre chiffre
        while len(chaine2)<4:
            chaine2+="0"
        return chaine2[:4]

    J'aimerais faire en sorte que la fonction puisse être appliquée à des mots lus dans un fichier texte.
    J'ai testé :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    import codecs
    f=codecs.open('names.txt','r',encoding='iso-8859-1')
    data=f.readlines()
    for word in data:
        soundex(word)
    Mais je ne sais pas trop si cela fonctionne car j'ai visiblement des erreurs d'encodage qui m'empêchent d'avoir un résultat

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    Traceback (most recent call last):
      File "D:/Cours/Linguistique et Informatique/S2/Exos/soundexnew.py", line 32, in <module>
        soundex(word)
      File "D:/Cours/Linguistique et Informatique/S2/Exos/soundexnew.py", line 6, in soundex
        chaine=chaine[0]+chaine[1:].replace(lettre,repl[mot])
    UnicodeDecodeError: 'ascii' codec can't decode byte 0xe2 in position 0: ordinal not in range(128)

  5. #5
    Membre expérimenté
    Homme Profil pro
    Inscrit en
    Mars 2007
    Messages
    941
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations forums :
    Inscription : Mars 2007
    Messages : 941
    Points : 1 384
    Points
    1 384
    Par défaut
    En ouvrant le fichier de cette manière, Python te renvoie des chaînes en unicode, donc tu devrais aussi définir tes autres chaînes en unicode, au moins pour les chaînes qui contiennent des caractères non-ASCII.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    repl = {u"âäà":"a",u"éèêë":"e",u"îï":"i",u"ôö":"o",u"ûùü":"u",u"ç":"c"," ":""}
    Et t'assurer que ton éditeur sauvegarde bien le script dans le même codec (iso-8859-1).

    Enfin je crois... C'est toujours pénible les problèmes d'encodage...

  6. #6
    Futur Membre du Club
    Profil pro
    Inscrit en
    Décembre 2008
    Messages
    13
    Détails du profil
    Informations personnelles :
    Âge : 38
    Localisation : France, Gironde (Aquitaine)

    Informations forums :
    Inscription : Décembre 2008
    Messages : 13
    Points : 5
    Points
    5
    Par défaut
    Effectivement d'après ce que j'ai vu sur le net, ça a l'air vraiment d'être le bazar l'encodage/décodage

    En tout cas, avec l'ajout de l'unicode dans les chaines contenant les non ASCII et d'une entête
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    # -*- coding: iso-8859-1 -*-
    en haut du script, ça à l'air de fonctionner nickel.

    Merci bien !

    Par contre, par rapport aux résultats affichés j'ai un souci avec :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    #Mise en forme du code sous forme Lettre chiffre chiffre chiffre
        while len(chaine2)<4:
            chaine2+="0"
        return chaine2[:4]
    Ca fonctionne correctement dans l'idle quand je teste avec des chaines lambda, mais quand il s'agit des noms lus dans le fichier texte, visiblement cela ne veut plus marcher.
    Je ne vois pas trop pourquoi...

  7. #7
    Membre expérimenté
    Homme Profil pro
    Inscrit en
    Mars 2007
    Messages
    941
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations forums :
    Inscription : Mars 2007
    Messages : 941
    Points : 1 384
    Points
    1 384
    Par défaut
    Ca manque un peu de détail.

    "Ca ne veut plus marcher" ? Ca veut dire quoi ? Il te renvoie une exception ? Laquelle ? Ou alors il ne renvoie pas une exception mais retourne un résultat incorrect ? Et qu'est-ce qu'un résultat correct (quel résultat attends-tu) ?

    Au lieu de:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    while len(chaine2)<4:
        chaine2+="0"
    return chaine2[:4]
    tu peux écrire:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    return chaine2[:4] + "0" * (4 - len(chaine2))
    Mais c'est équivalent, ça ne devrait pas résoudre ton problème.

  8. #8
    Futur Membre du Club
    Profil pro
    Inscrit en
    Décembre 2008
    Messages
    13
    Détails du profil
    Informations personnelles :
    Âge : 38
    Localisation : France, Gironde (Aquitaine)

    Informations forums :
    Inscription : Décembre 2008
    Messages : 13
    Points : 5
    Points
    5
    Par défaut
    Hmm oui pardon j'ai pas vraiment précisé et je n'ai pas mis le code en entier vu qu'il était déjà plus haut :p

    Donc le soundex transforme les mots en un code LettreChiffreChiffreChiffre+

    Selon la longueur des mots et le nombre de lettres codées dans ceux-ci, le code se limite parfois à LettreChiffre ou LettreChiffreChiffre.

    Mais il faut toujours avoir pour résultat un code LettreChiffreChiffreChiffre.

    Donc le but du bout de code concerné est de compléter par des zéros jusqu'à obtenir 3 chiffres après la lettre s'il y en a moins : tant que la longueur de la chaine est inférieure à 4, compléter par des zéros.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     while len(chaine2)<4:
        chaine2+="0"
    Et donc, comme résultat, il me renvoie des codes incomplets : les zéros ne sont pas ajoutés (dans aucun cas).

    Est là pour "couper" les codes qui au contraire sont trop longs et excèdent 4 caractères et afficher seulement le début.


    Extrait de résultats :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    L126
    L126
    J96
    B476
    K65
    T4
    On devrait avoir :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    L126
    L126
    J960
    B476
    K650
    T400

  9. #9
    Membre éprouvé

    Profil pro
    Inscrit en
    Août 2004
    Messages
    723
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2004
    Messages : 723
    Points : 923
    Points
    923
    Par défaut
    Après quelques essais, j'ai trouvé un comportement inattendu si jamais dans le texte il y a des retours à la ligne, qui ne sont pas supprimés
    Je te conseille donc de les supprimer en même temps que les espaces (au cas où, j'ai ajouté aussi les tabulations) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    repl = {"âäà":"a","éèêë":"e","îï":"i","ôö":"o","ûùü":"u","ç":"c"," \t\n\r":""}

  10. #10
    Membre extrêmement actif
    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
    Points : 1 658
    Points
    1 658
    Par défaut
    Tu as raison, Sycosis, je me suis planté. Ton tout premier code (une fois rétablie l'indentation correcte) tourne bien, même avec plusieurs éléments dans les listes. C'est un peu spécial de faire deux itérations parallèles corrélées, l'une sur élément de liste, l'autre sur indice permettant de parcourir une liste, mais bon après tout si ça marche.....
    Je ne comprends pas ce que j'ai foutu. Je n'ai pas dû pour une fois faire tourner ton code, comme je le fais habituellement toujours. J'ai dû me fier à la seule compréhension de ton code en le lisant.


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

    Ceci dit, j'avais bien compris que d'autres types de transformations allaient s'ajouter à celle que tu traitais dans ce premier code, et qu'il fallait un code qui traite des listes à plusieurs éléments. C'est aussi pourquoi j'ai éclaté "AEIOUYWH" en trois chaines "AEI","OU","YWH" , pour être sûr que le code que j'ai proposé était valable.
    Mais ça ne présentait qu'un intérêt temporaire.
    Il faut rassembler à nouveau au maximum toutes les lettres en une seule chaine "AEIOUYWH", et même, puisque tu as donné les transformations supplémentaires, tout aggréger dans la mesure du possible.

    J'ai donc apporté un certain nombre de modifs à ton code:
    - aggrégation des traitements
    - J'ai mis des remplaçantes majuscules pour les ""âäàéèêëîï...etc" ce qui permet de se passer de chaine=chaine.upper() valable uniquement pour ces caractères, et donc de grouper ce traitement avec les autres remplacements.
    - utilisation d'une manière agréable de construire le dictionnaire, avec sa vérification d'une manière ordonnée
    - une expression condensée pour éliminer les doublons,triplons, et autres x-plons
    - return condensé dans lequel on ajoute les zéros nécessaires


    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
    def soundex(chaine):
        # Remplacement des caractères accentués
        # {"âäà":"A","éèêë":"E","îï":"I","ôö":"O","ûùü":"U","ç":"C"}
        # Remplacemet des lettres restantes par le code associé
        # {"BP":"1","CKQ":"2","DT":"3","L":"4","MN":"5","R":"6","GJ":"7","XZS":"8","FV":"9"}
        # Suppression des voyelles, w et h, des virgules,points etc et des espaces éventuels
        # {"AEIOUYWH,.;: ":""}
        # Toutes ces transformations en gardant la première lettre de la chaine
        tupla = ("âäà","éèêë","îï","ôö","ûùü","ç","BP","CKQ","DT","L","MN","R","GJ","XZS","FV","AEIOUYWH,.;: \t\n\r")
        tuplb = ("A","E","I","O","U","C","1","2","3","4","5","6","7","8","9","")
        repl = dict(zip(tupla,tuplb))
        print 'Vérification du dictionnaire :'
        for el in tupla:
            repel = repl[el]
            if repel=='':
                repel = ['']
            if '\t' in el or '\n' in el or '\r' in el:
                el = [el]
            print el,'\t: ',repel
        print
        for mot in tupla:
            for lettre in mot:
                chaine=chaine[0]+chaine[1:].replace(lettre,repl[mot])
                print [lettre],'\t',[repl[mot]],'  ',chaine
     
        #Suppression des doublons
        chaine = ''.join([ u for u,v in zip(chaine,chaine[1:]) if u!=v])+chaine[-1]
        print '\nchaine sans doublons =',chaine
     
        #Mise en forme du code sous forme Lettre chiffre chiffre chiffre
        return (chaine+'0000')[0:4]
     
     
     
    ch = "âäà éèêë îï ôö ûùü ç BEFORE THE END OF THE DAY, THE RED CAT WAS DEAD"
    chaine = soundex(ch)
    print '\n-----------------------\n\nquadruplet final =',chaine,'\n'
    Je ne me suis pas occupé des histoires de u" " pour Unicode, n'y comprenant pas grand chose et n'ayant pas eu de problème pour faire tourner ce code tel quel.

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


    Mais ces améliorations sont mineures devant la seule amélioration bonifiante à mon sens.
    Je suis surpris de voir que personne ne s'est intéressé à ma suggestion de translate() qui est la vraie bonne solution
    , alors que je l'ai signalée en orange, que j'ai donné un lien et que dividee dont j'en ai appris l'usage soit intervenu. Il va falloir te coucher moins tard et te lever moins tôt, dividee

    Il n'y a que deux lignes pour faire tout le boulot:

    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
    def soundex(chaine):
     
        # Suppression des caractères accentués, des voyelles, de w et h et y,
        # des virgules,points etc , des espaces ,des tabulations et des retours à la ligne spécifiée par
        # "âäàéèêëîïôöûùüçÂÄÀÉÈÊËÎÏÔÖÛÙÜÇaeiouAEIOUwhyWHY,.;: \t\n\r"
        # en deuxième argument de translate()
     
        # Remplacement des lettres restantes suivant le code
        # {"BP":"1","CKQ":"2","DT":"3","L":"4","MN":"5","R":"6","GJ":"7","XZS":"8","FV":"9"}
        # spécifié par la table maketrans("BPCKQDTLMNRGJXZSFV","112223345567788899")
        # en premier argument de translate()
     
         # Toutes ces transformations en gardant la première lettre de la chaine intacte
     
        print '\nchaine traitée = ',chaine
     
        chu = chaine[1:].upper().translate(tabl,eliminables)
        print 'chaine[1:].upper().translate(tabl,eliminables) =',chu
     
        # Suppression des doublons et mise en forme du code sous forme Lettre chiffre chiffre chiffre
        # dans le renvoi
        return ( 'quadruplet final = ',(chaine[0]+''.join([ v for u,v in zip(' '+chu,chu) if u!=v])+'0000')[0:4] )
     
     
    #----------------------------------------------------------------------------
     
    eliminables = "ÂÄÀÉÈÊËÎÏÔÖÛÙÜAEIOUWHY,.;: \t\n\r"
    print 'Les caractères éliminés sont, après mise en majuscules:\n"ÂÄÀÉÈÊËÎÏÔÖÛÙÜÇAEIOUWHY,.;: \\t\\n\\r"'
     
    from string import maketrans
    tabl = maketrans("BPÇCKQDTLMNRGJXZSFV","1122223345567788899")
    print '\nVérification de la table de codage:'
    print "BPCKQDTLMNRGJXZSFV".replace('',' ')
    print "BPCKQDTLMNRGJXZSFV".translate(tabl).replace('',' ')
     
    ch = "âäà éèêë îï ôö ûùü çCçC BEFORE THE END OF THE DAY, THE RED CAT WAS DEAD"
    a,b = soundex(ch)
    print a,b,'\n'
     
    ch = "2âäà éèêë îï ôö ûùü çCçC BEFORE THE END OF THE DAY, THE RED CAT WAS DEAD"
    a,b = soundex(ch)
    print a,b,'\n'
    L'élimination des doublons se fait par
    ''.join([ v for u,v in zip(' '+chu,chu) if u!=v])
    en employant une méthode avec zip pour pouvoir écrire une list comprehension, parce qu'on ne peut pas faire des additions ou des concaténations dans les lists comprehension.

    Il y a une astuce dans cette élimination des doublons:

    - le traitement doit se faire sans toucher au premier caractère de chaine, donc on est obligé de traiter avec translate() seulement chaine[1:] :
    le résultat est une chaine de chiffres chu = '7637651220878734'

    - l'élimination des doublons se fait sur chu car de toutes façons même si on la faisait sur chaine[0]+chu, le premier caractère de chu (un chiffre) ne serait jamais éliminé puisque toujours différent de la lettre qui le précède.

    Or en utilisant zip(' '+chu,chu) pour l'élimination des doublons, on n'élimine jamais le premier caractère de chu,
    parce que le ' ' dans le premier argument de zip permet de toujours conserver le premier caractère dans le deuxième argument puisqu'on compare ce dernier avec un blanc ' ' .

    L'astuce est donc que ce blanc ' ' permet en même temps d'obtenir le décalage pour comparer chaque lettre de la chaine située en deuxième argument avec sa précedente située en premier argument,
    et d'éviter d'éliminer le premier caractère de chu.

    Ouf......

    Tout ceci n'est valable que si le premier caractère de chaine est bien une lettre ou s'il ne faut jamais le modifier même s'il s'agit d'un chiffre.
    À voir.

    En tous cas avec ce code:
    Les caractères éliminés sont:
    "ÂÄÀÉÈÊËÎÏÔÖÛÙÜÇAEIOUWHY,.;: \t\n\r"

    Vérification de la table de codage:
    B P C K Q D T L M N R G J X Z S F V
    1 1 2 2 2 3 3 4 5 5 6 7 7 8 8 8 9 9

    chaine traitée = âäà éèêë îï ôö ûùü çCçC BEFORE THE END OF THE DAY, THE RED CAT WAS DEAD
    chaine[1:].upper().translate(tabl,eliminables) = 222219635393336323833
    quadruplet final = â219


    chaine traitée = 2âäà éèêë îï ôö ûùü çCçC BEFORE THE END OF THE DAY, THE RED CAT WAS DEAD
    chaine[1:].upper().translate(tabl,eliminables) = 222219635393336323833
    quadruplet final = 2219

  11. #11
    Futur Membre du Club
    Profil pro
    Inscrit en
    Décembre 2008
    Messages
    13
    Détails du profil
    Informations personnelles :
    Âge : 38
    Localisation : France, Gironde (Aquitaine)

    Informations forums :
    Inscription : Décembre 2008
    Messages : 13
    Points : 5
    Points
    5
    Par défaut
    Merci beaucoup pour toutes ces réponses et améliorations.
    Concernant le translate, j'avais regardé l'exemple de dividee que tu avais linké mais je ne me sentais pas trop de tenter des manipulations avec, sachant que j'ai déjà du mal avec des choses assez simples.

    Je vais étudier le code que tu as laissé histoire d'essayer d'assimiler tout ça.
    Je pense que l'on peut considérer le topic comme résolu.

Discussions similaires

  1. [Tableaux] Opérations sur une chaine
    Par Ben-o dans le forum Langage
    Réponses: 6
    Dernier message: 09/12/2008, 16h47
  2. fread sur une chaine de caractere ?
    Par Battosaiii dans le forum C
    Réponses: 17
    Dernier message: 18/03/2006, 12h50
  3. Masque sur une chaine
    Par Weedo dans le forum Algorithmes et structures de données
    Réponses: 1
    Dernier message: 10/01/2006, 11h32
  4. Erreur de segmentation sur une chaine en récursif...
    Par laurent_ifips dans le forum C
    Réponses: 12
    Dernier message: 13/12/2005, 16h04
  5. [Débutant][String] Opérations sur une chaîne
    Par gandalf_le_blanc dans le forum Général Java
    Réponses: 8
    Dernier message: 08/06/2004, 11h59

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