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 :

Travail sur des Strings


Sujet :

Python

Vue hybride

Pingvince Travail sur des Strings 24/10/2007, 13h12
Guigui_ pour manipuler les string:... 24/10/2007, 14h22
pacificator Bonjour, tu peux aussi... 24/10/2007, 14h26
Pingvince Merci pour vos réponses. ... 24/10/2007, 14h49
Pingvince J'arrive à obtenir quelque... 26/10/2007, 02h32
Pingvince Nouvelle question sur les... 12/11/2007, 08h33
Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre habitué
    Inscrit en
    Octobre 2007
    Messages
    15
    Détails du profil
    Informations forums :
    Inscription : Octobre 2007
    Messages : 15
    Par défaut Travail sur des Strings
    Bonjour,

    Je suis débutant en Python et j'aimerais essayer de faire des modifications sur des chaines de caractères. Par exemple avec une chaine de départ comme celle-ci :
    "(5, A, 2), (3, B, 4)"
    Je voudrais générer les chaines suivantes (en appliquant + ou - 1 sur chacune des valeurs numériques, et en traitant tous les cas possibles).

    "(4, A, 1), (3, B, 4)"
    "(4, A, 2), (3, B, 4)"
    "(4, A, 3), (3, B, 4)"
    "(5, A, 1), (3, B, 4)"
    "(5, A, 3), (3, B, 4)"
    "(6, A, 1), (3, B, 4)"
    "(6, A, 2), (3, B, 4)"
    "(6, A, 3), (3, B, 4)"

    "(5, A, 2), (2, B, 3)"
    "(5, A, 2), (2, B, 4)"
    "(5, A, 2), (2, B, 5)"
    "(5, A, 2), (3, B, 3)"
    "(5, A, 2), (3, B, 5)"
    "(5, A, 2), (4, B, 3)"
    "(5, A, 2), (4, B, 4)"
    "(5, A, 2), (4, B, 5)"

    "(4, A, 1), (2, B, 3)"
    "(4, A, 1), (2, B, 4)"
    "(4, A, 1), (2, B, 5)"
    "(4, A, 1), (3, B, 3)"
    "(4, A, 1), (3, B, 5)"
    "(4, A, 1), (4, B, 3)"
    "(4, A, 1), (4, B, 4)"
    "(4, A, 1), (4, B, 5)"

    "(4, A, 3), (2, B, 3)"
    "(4, A, 3), (2, B, 4)"
    "(4, A, 3), (2, B, 5)"
    "(4, A, 3), (3, B, 3)"
    "(4, A, 3), (3, B, 5)"
    "(4, A, 3), (4, B, 3)"
    "(4, A, 3), (4, B, 4)"
    "(4, A, 3), (4, B, 5)"

    "(5, A, 1), (2, B, 3)"
    etc...



    L'idéal serait que ce soit appliquable sur une chaine de départ de longueur variable (avec un nombre non défini d'éléments, un élément étant '(nombre, lettre, nombre)'). Ce n'est pas une erreur je veux bien travailler sur des chaines.

    Pourriez vous m'aiguillez sur comment réaliser celà, car j'ai vu qu'en python on peut faire les choses très simplement en très peu de lignes !
    Désolé si l'exemple est un peu long.

    Pingvince

  2. #2
    Expert confirmé
    Avatar de Guigui_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Août 2002
    Messages
    1 864
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Saône et Loire (Bourgogne)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Enseignement

    Informations forums :
    Inscription : Août 2002
    Messages : 1 864
    Par défaut
    pour manipuler les string: http://python.developpez.com/faq/?page=String
    Ensuite, tes nombres et lettres sont toujours à la même position (position: 1, 4, 7, 12, 15, 18, 23, ... (suite qu'il facile de générer dans une boucle for).
    ensuite
    Pour savoir si tu une chaine ou un caractère est un nombre, applique la fonction isdigit()
    => => pour convertir un string en int => int(monstring)
    ...

  3. #3
    Membre Expert Avatar de pacificator
    Profil pro
    Inscrit en
    Août 2006
    Messages
    1 074
    Détails du profil
    Informations personnelles :
    Âge : 45
    Localisation : France

    Informations forums :
    Inscription : Août 2006
    Messages : 1 074
    Par défaut
    Bonjour,

    tu peux aussi utiliser les fonctionnalités de formatage de chaîne:
    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
    import string
     
    chaine = "(5, A, 2), (3, B, 4)" # chaine initiale
    values = [] # liste des valeurs de depart
    liste = [] # liste temporaire
     
    for car in chaine:
        if car in string.letters or car in string.digits:
            liste.append('%s')
            values.append(car)
        else:
            liste.append(car)
     
    chaine = "".join(liste)
     
    # la chaine avec les caracteres de formatage
    print chaine
    # (%s, %s, %s), (%s, %s, %s)
    # exemple d'utilisation
    print chaine % tuple([chr(ord(car) +1) for car in values])
    # (6, B, 3), (4, C, 5)
    Il te reste à créer les fonctions pour modifier la liste des valeurs.

    Bon python.

  4. #4
    Membre habitué
    Inscrit en
    Octobre 2007
    Messages
    15
    Détails du profil
    Informations forums :
    Inscription : Octobre 2007
    Messages : 15
    Par défaut
    Merci pour vos réponses.

    Pour Guigui_, je veux bien travailler sur des chaines, donc mes indices seraient 1, 12, etc...

    Avec vos 2 propositions, je risque aussi d'avoir des problèmes si ma chaine de départ est "(5, A, 222), (3, B, 4)" car dans ce cas je ne pourrais pas retrouver mes 2 nombres 222 et 3 pour leur appliquer + et - 1, ou je me trompe ?

    PS. Les lettres restent les mêmes.
    Et oui il va falloir que je fasse des fonctions pour être sûr d'avoir traité tous les cas possibles !

    J'ai modifié ton code pacificator et j'ai un peu avancé.

    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
    import string
     
    chaine = "(5, A, 8)" # chaine initiale
    values = [] # liste des valeurs de depart
    liste = [] # liste temporaire
     
    for car in chaine:
        if car in string.digits:
            liste.append('%s')
            values.append(car)
        else:
            liste.append(car)
     
    chaine = "".join(liste)
     
    # la chaine avec les caracteres de formatage
    print "Chaine avec caractere de formatage =", chaine
    # Chaine avec caractere de formatage = (%s, A, %s)
    # exemple d'utilisation
    listAll = []
    listNewNb = []
    for nb in values:
        listNewNb.append(int(nb) -1)
        listNewNb.append(int(nb))
        listNewNb.append(int(nb) +1)
        listAll.append(listNewNb)
        listNewNb = []
     
    print "listAll=", listAll
    #listAll= [[4, 5, 6], [7, 8, 9]]
     
    firstFlag = True
    firstSet = []
    for listNewNb in listAll:
        if not firstFlag:
    	for nb in firstSet:
    	    print chaine % tuple([nb, listNewNb[0]])
    	    print chaine % tuple([nb, listNewNb[1]])
    	    print chaine % tuple([nb, listNewNb[2]])
    	    firstFlag = True
        else:
    	firstSet = listNewNb
    	firstFlag = False
    Et j'obtiens :
    (4, A, 7)
    (4, A, 8)
    (4, A, 9)
    (5, A, 7)
    (5, A, 8)
    (5, A, 9)
    (6, A, 7)
    (6, A, 8)
    (6, A, 9)

    (Bon j'ai encore le (5, A, 8) en trop mais c'est pas dur de l'enlever je pense). Je continue donc là dessus pour essayer que cela marche aussi avec une chaine de départ de 2 éléments (ou plus) mais ca m'a l'air déjà beaucoup plus compliqué ! Si vous avez quelques conseils je les prends !

  5. #5
    Membre habitué
    Inscrit en
    Octobre 2007
    Messages
    15
    Détails du profil
    Informations forums :
    Inscription : Octobre 2007
    Messages : 15
    Par défaut
    J'arrive à obtenir quelque chose comme celà :

    Ma liste de valeurs possibles: listAll= [[4, 5, 6], [7, 8, 9], [2, 3, 4], [3, 4, 5]]
    Avec les lettres correspondantes: listLetters: ['A', 'B']

    Et j'arrive à générer les éléments séparéments comme ceci:
    (4, A, 7)
    (4, A, 8)
    (4, A, 9)
    (5, A, 7)
    (5, A, 8)
    (5, A, 9)
    (6, A, 7)
    (6, A, 8)
    (6, A, 9)
    (2, B, 3)
    (2, B, 4)
    (2, B, 5)
    (3, B, 3)
    (3, B, 4)
    (3, B, 5)
    (4, B, 3)
    (4, B, 4)
    (4, B, 5)


    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
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    import string
     
    chaine = "(5, A, 8), (3, B, 4)" # chaine initiale
    values = [] # liste des valeurs de depart
    liste = [] # liste temporaire
    listLetters = []
     
    chaines = chaine.split("), (")
    chaines[0] = chaines[0].strip('(')
    chaines[-1] = chaines[-1].strip(')')
    print chaines
    #['5, A, 8', '3, B, 4']
     
     
    for chaine in chaines:
        for car in chaine:
            if car in string.digits:
                liste.append('%s')
                values.append(car)
            else:
                liste.append(car)
    	    if str(car).isalpha():
    		listLetters.append(car)
     
        liste.append(', ')
        chaine = "".join(liste)
    chaine.strip(", ")
    print chaine
    # %s, A, %s, %s, B, %s, 
     
    print "listLetters=", listLetters
    #['A', 'B']
     
     
     
    # exemple d'utilisation
    listAll = []
    listNewNb = []
    for nb in values:
        listNewNb.append(int(nb) -1)
        listNewNb.append(int(nb))
        listNewNb.append(int(nb) +1)
        listAll.append(listNewNb)
        listNewNb = []
     
    print "listAll=", listAll
    #listAll= [[4, 5, 6], [7, 8, 9], [2, 3, 4], [3, 4, 5]]
     
     
    chaineFormatee = "(%s, %s, %s)"
    firstFlag = True
    firstSet = []
    indLetter = 0
    compteLetter = 0
    for idx,listNewNb in enumerate(listAll):
        if not firstFlag:
    	for nb in firstSet:
    	    print chaineFormatee % tuple([nb, listLetters[indLetter],listNewNb[0]])
    	    print chaineFormatee % tuple([nb, listLetters[indLetter],listNewNb[1]])
    	    print chaineFormatee % tuple([nb, listLetters[indLetter],listNewNb[2]])
    	    compteLetter = compteLetter +1
    	    if compteLetter == 3:
     	        indLetter = indLetter+1
    		compteLetter = 0
    	    firstFlag = True
    	    firstSet = []
        else:
    	firstSet = listNewNb
    	firstFlag = False
    Comment à partir de celà puis-je générer toutes mes chaines comme dans mon 1er exemple ? Suis-je sur la bonne voix ou pas ?

    Et comment puis -je généraliser ce cas, pour que cela marche avec des chaines de départ de longueur différentes : "(5, A, 8)" ou "(5, A, 8), (3, B, 4)" ou "(5, A, 8), (3, B, 4), (7, C, 2)" ?

  6. #6
    Membre habitué
    Inscrit en
    Octobre 2007
    Messages
    15
    Détails du profil
    Informations forums :
    Inscription : Octobre 2007
    Messages : 15
    Par défaut Nouvelle question sur les strings: optimisation
    Bonjour,
    J'ai une question du même genre sur les chaînes. Je veux récupérer les nombres qui se trouvent dans un texte. Mais seulement ceux qui sont derrière un '#'.
    J'ai fait ceci qui fonctionne, mais je voudrais savoir si je peux l'améliorer, car je fais ceci dans de très longues boucles et ca prend beaucoup de temps à s'exécuter.

    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 string
     
    description = "Ticket Id=120, Owner=tgor3401, Time=2006-09-08 16:14:20, Desc=SVNng short of a r=tgor3401, time=26:19:52 code. #124 #125 #126.Ticket 120 author=tgor3401, time=2006-09-15 15:19:21, , newvalue=closed. (#98) Ticket 120 author=tgor3401t.."
     
    strT = description + " "
    posB=0
    strSearchTicket = "#"
    posA = strT.find(strSearchTicket)
    strTemp = ""
    while posA !=-1:
      strT = strT[posA+1:]
      posB = 0
      while strT[posB].isdigit():
        posB = posB +1
      strTemp = strT[:posB]
      if (strTemp) :
        print strTemp
      strT = strT[posB:]
      posA = strT.find(strSearchTicket)
     
    #124
    #125
    #126
    #98

  7. #7
    Membre chevronné Avatar de Pierre Maurette
    Profil pro
    Inscrit en
    Juillet 2002
    Messages
    283
    Détails du profil
    Informations personnelles :
    Âge : 69
    Localisation : France

    Informations forums :
    Inscription : Juillet 2002
    Messages : 283
    Par défaut
    Citation Envoyé par Pingvince Voir le message
    Bonjour,
    J'ai une question du même genre sur les chaînes. Je veux récupérer les nombres qui se trouvent dans un texte. Mais seulement ceux qui sont derrière un '#'.
    J'ai fait ceci qui fonctionne, mais je voudrais savoir si je peux l'améliorer, car je fais ceci dans de très longues boucles et ca prend beaucoup de temps à s'exécuter.

    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 string
     
    description = "Ticket Id=120, Owner=tgor3401, Time=2006-09-08 16:14:20, Desc=SVNng short of a r=tgor3401, time=26:19:52 code. #124 #125 #126.Ticket 120 author=tgor3401, time=2006-09-15 15:19:21, , newvalue=closed. (#98) Ticket 120 author=tgor3401t.."
     
    strT = description + " "
    posB=0
    strSearchTicket = "#"
    posA = strT.find(strSearchTicket)
    strTemp = ""
    while posA !=-1:
      strT = strT[posA+1:]
      posB = 0
      while strT[posB].isdigit():
        posB = posB +1
      strTemp = strT[:posB]
      if (strTemp) :
        print strTemp
      strT = strT[posB:]
      posA = strT.find(strSearchTicket)
     
    #124
    #125
    #126
    #98
    Je ne sais pas si ça va être plus rapide, mais c'est bien compliqué, votre truc.
    Avec des regex (import re) la réponse tient en une seule ligne:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    print re.findall('#\d+', description)
    ou certainement plus efficace dans un vrai programme:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    pat = re.compile('#\d+')
    print re.findall(pat, description)
    Si vous ne voulez pas les '#' dans les chaines:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    print re.findall('(?<=#)\d+', description)
    Si vous voulez autoriser les '+' et les '-':
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    print re.findall('(?<=#)[-+]?\d+', description)
    Si vous ne voulez pas utiliser les regex, vous pouvez dégrossir avec un split('#') (le '-' sert à être sûr que la première occurrence ne commencez pas par '#'):
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    for chunk in  ('-' + description).split('#')[1:]:
      print chunk.split()[0].split('.')[0].split(')')[0]
    La dernière ligne est un peu improvisée. En fait, ça vient du fait que comme souvent avec ce genre de question le problème n'est qu'imparfaitement défini. Peut-il y avoir un espace entre '#' et le premier chiffre ? Peut-il y avoir un nombre "à virgule" ? etc.
    En fait, si vous définissez le problème par l'exemple, je réponds:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    print '#124\n#125\n#126\n#98'

    Bonne journée...

Discussions similaires

  1. [VB]Travailler sur un string
    Par Little-Freud dans le forum VB 6 et antérieur
    Réponses: 17
    Dernier message: 21/05/2006, 16h05
  2. Débutant travailler sur des images
    Par doud dans le forum Bibliothèques
    Réponses: 1
    Dernier message: 15/08/2005, 15h47
  3. [débutant]travailler sur contenu string
    Par Serge76 dans le forum SL & STL
    Réponses: 13
    Dernier message: 06/11/2004, 16h43
  4. Travailler sur des sources distantes avec Eclipse
    Par El Saigneur dans le forum Eclipse Java
    Réponses: 5
    Dernier message: 12/07/2004, 09h40
  5. Travailler sur des données qui doivent être triées
    Par haypo dans le forum XML/XSL et SOAP
    Réponses: 2
    Dernier message: 19/07/2003, 17h13

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