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 :

programme méthode split


Sujet :

Python

  1. #1
    Membre averti
    Femme Profil pro
    Inscrit en
    Décembre 2013
    Messages
    21
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France

    Informations forums :
    Inscription : Décembre 2013
    Messages : 21
    Par défaut programme méthode split
    Bonjour, j'aimerais obtenir de l'aide pour modifier un programme afin de ne pas utiliser la méthode split. Le but est d'échanger les mots 2 à 2 :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    def changmot(phrase):
        s=phrase.split()
        if len(s)==1:
            return(phrase)
        elif len(s)%2==0:
            for c in range(0,len(s),2):
                s[c],s[c+1]=s[c+1],s[c]
            return" ".join(s)
        else:
            for c in range(0,len(s)-1,2):
                s[c],s[c+1]=s[c+1],s[c]
            return" ".join(s)
    Merci d'avance.

  2. #2
    Invité
    Invité(e)
    Par défaut
    Je ne comprends pas bien le but de la question. Parce que si on ne peut pas utiliser la function split prédéfinie, on est pratiquement obligé de réécrire une function split, et on ne gagne rien.

    Par ailleurs, je crois qu'on peut écrire la fonction plus simplement:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    def changmot(phrase):
        s= phrase.split()
        for c in range(0, len(s) - 1, 2):
            s[c], s[c+1]= s[c+1], s[c]
        return " ".join(s)
    Dernière modification par Invité ; 27/12/2013 à 23h47.

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

    Moi non plus, je ne vois rien de plus élégant que le code proposé par YvDao.

    S'il fallait absolument remplacer la méthode split, ce serait possible, mais ça conduit à une grosse fonction. Par exemple:

    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
    def split2(ch):
        liste = []
        i1, i2, lg = 0, 0, len(ch)
        whitespace = [' ', '\x09', '\x0A', '\x0D', '\x0C', '\x0B']
        # recherche du 1er caractère non-whitespace
        while i2<len(ch) and ch[i2] in whitespace:
            i2 += 1
        i1 = i2
        # recherche des mots
        while True:
              while i2<lg and ch[i2] not in whitespace:
                    i2 += 1
              liste.append(ch[i1:i2])
              i1 = i2
              if i2>=lg:
                 break # fin de la chaine
              # neutralisation d'une suite de caractères whitespace
              while i2<lg and ch[i2] in whitespace:
                    i2 += 1
              i1 = i2
              if i2>=lg:
                 break # fin de la chaine
        return liste
    Exemple d'utilisation et comparaison pour vérifier avec la méthode split:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    ch = "   Que j'aime à faire \r\n apprendre    un nombre utile aux     sages   "
    print split2(ch)
    print ch.split()
    Affichage:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    ['Que', "j'aime", 'à', 'faire', 'apprendre', 'un', 'nombre', 'utile', 'aux', 'sages']
    ['Que', "j'aime", 'à', 'faire', 'apprendre', 'un', 'nombre', 'utile', 'aux', 'sages']

  4. #4
    Membre averti
    Femme Profil pro
    Inscrit en
    Décembre 2013
    Messages
    21
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France

    Informations forums :
    Inscription : Décembre 2013
    Messages : 21
    Par défaut
    Merci pour vos réponses, la méthode de YvDao est en effet bien plus simple.
    En fait le but n'est pas à proprement parler de refaire une fonction split, mais de faire une fonction qui m'amène au même résultat (changer les mots 2 à 2) sans utiliser "split". Apparemment c'est faisable sans trop de difficultés mais je ne vois pas comment. Il y a peut être un moyen de contourner la méthode split en s'y prenant différemment.
    Si vous avez des idées je suis preneuse.

  5. #5
    Invité
    Invité(e)
    Par défaut
    Il n'y a pas moyen de permuter les mots sans les délimiter et pour cela il faut chercher les blancs séparateurs. C'est ce que fait split. C'est incontournable.

    Il y a moyen de construire la chaîne résultat sans passer par une liste de chaînes (via split et join), mais ce serait bien de préciser si c'est cela que tu veux éviter.

    Peut-on savoir d'où provient cette contrainte ?

  6. #6
    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
    Même question que YvDao.

    A la rigueur, en utilisant une partie de mon code ci-dessus, on peut faire que la fonction renvoie les mots un par un (avec yield), ce que split ne sait pas faire:

    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
    def split2(ch):
        i1, i2, lg = 0, 0, len(ch)
        whitespace = [' ', '\x09', '\x0A', '\x0D', '\x0C', '\x0B']
        # recherche du 1er caractère non-whitespace
        while i2<len(ch) and ch[i2] in whitespace:
            i2 += 1
        i1 = i2
        # recherche des mots
        while True:
              while i2<lg and ch[i2] not in whitespace:
                    i2 += 1
              yield ch[i1:i2]
              i1 = i2
              if i2>=lg:
                 break # fin de la chaine
              # neutralisation d'une suite de caractères whitespace
              while i2<lg and ch[i2] in whitespace:
                    i2 += 1
              i1 = i2
              if i2>=lg:
                 break # fin de la chaine
     
    ch = u"Que j'aime à faire \r\n apprendre    un nombre utile aux     sages"
    for mot in split2(ch):
        print mot
    Que
    j'aime
    à
    faire
    apprendre
    un
    nombre
    utile
    aux
    sages
    [Edit] Ci-dessous version simplifiée de la fonction:

    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
    def split2(ch):
        i1, i2, lg = 0, 0, len(ch)
        whitespace = [' ', '\x09', '\x0A', '\x0D', '\x0C', '\x0B']
        # recherche des mots
        while True:
              # neutralisation des caractères whitespace
              while i2<lg and ch[i2] in whitespace:
                    i2 += 1
              if i2>=lg:
                 break # fin de la chaine
              i1 = i2
              # recherche du mot
              while i2<lg and ch[i2] not in whitespace:
                    i2 += 1
              yield ch[i1:i2] # renvoi du mot trouvé
              if i2>=lg:
                 break # fin de la chaine
              i1 = i2

  7. #7
    Membre averti
    Femme Profil pro
    Inscrit en
    Décembre 2013
    Messages
    21
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France

    Informations forums :
    Inscription : Décembre 2013
    Messages : 21
    Par défaut
    Le but est d'utiliser au minimum les fonctions prédéfinies de python dont j'ignore la complexité, sinon je peux déterminer la complexité de ma fonction. Alors s'il y a un moyen sans passer par une liste de chaînes ça serait très bien.

  8. #8
    Invité
    Invité(e)
    Par défaut
    Je comprends mieux.

    Il y a fort à parier que la fonction split a une complexité linéaire pour ce qui est de la détection des blancs; on voit mal comment on pourrait faire moins bien.

    Par contre, pour ce qui est de la complexité de la création de la liste de chaînes, on est en droit de se poser la question, étant donné les allocations dynamiques dont le coût est inconnu.

    Mêmes remarques pour join.

    Malheureusement le problème se pose de toutes façons pour ce qui est de la création de la chaîne permutée, vu que les chaînes sont immuables et ne peuvent être modifiées sur-place. Surtout que la concaténation peut facilement mener à une complexité quadratique !?

    A ce propos, je ne serais pas étonné que la fonction join ait un meilleur comportement (linéaire) que ce qu'on peut obtenir en programmant soi-même.
    Dernière modification par Invité ; 27/12/2013 à 23h27.

  9. #9
    Membre très actif Avatar de Kurodiam
    Inscrit en
    Décembre 2013
    Messages
    208
    Détails du profil
    Informations forums :
    Inscription : Décembre 2013
    Messages : 208
    Par défaut
    Ce qui est bizarre , c'est que j'ai testé la fonction changmot est çà répond pas quand je mets une liste .Déjà que représente la lettre 'c' .
    La fonction split est sensée séparée juste , non ?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    >>> def changmot(phrase):
    	s= phrase.split()
    	for c in range(0, len(s) - 1, 2):
    		s[c], s[c+1]= s[c+1], s[c]
    		return " ".join(s)>>> changmot('zut')
    >>> phrase= 'zut'
    >>> changmot(phrase)             # çà marche pas .
    >>> changmot("zut")
    >>> s='zut'.split()
    >>> s
    ['zut']
    Est-ce que le double de l’élément du vecteur çà veut dire les mots 2 à 2 ?

    PS : les mots 2 à 2 , çà veut dire sauter de 2 cases genre ?

  10. #10
    Invité
    Invité(e)

  11. #11
    Membre très actif Avatar de Kurodiam
    Inscrit en
    Décembre 2013
    Messages
    208
    Détails du profil
    Informations forums :
    Inscription : Décembre 2013
    Messages : 208
    Par défaut
    Merci pour l'info .Je vais jeter un coup d’œil

  12. #12
    Membre averti
    Femme Profil pro
    Inscrit en
    Décembre 2013
    Messages
    21
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France

    Informations forums :
    Inscription : Décembre 2013
    Messages : 21
    Par défaut
    Est-ce qu'il n'y aurait pas moyen de noter dans une liste les indices de l'apparition des espaces dans la phrase, comme cela :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    def change(phrase):
        liste=[0]
        for i in range(0,len(phrase)):
            if phrase[i]==" " :
                liste.append(i)
                print(liste)
    et de s'en servir ensuite pour créer une nouvelle liste où on ajouterait les caractères de la phrase découpés selon les indices : par exemple
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    resultat+=phrase[2:6]
    resultat+=phrase[0:6]
    si l'espace se situe en indice 2 dans la phrase de départ ? par exemple "je veux" se verrait retourner "veux je" ?

  13. #13
    Membre émérite
    Homme Profil pro
    Aucune activité
    Inscrit en
    Novembre 2011
    Messages
    505
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Aucune activité

    Informations forums :
    Inscription : Novembre 2011
    Messages : 505
    Par défaut
    Bonjour,

    Citation Envoyé par info-python Voir le message
    Est-ce qu'il n'y aurait pas moyen de noter dans une liste les indices de l'apparition des espaces dans la phrase, comme cela :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    def change(phrase):
        liste=[0]
        for i in range(0,len(phrase)):
            if phrase[i]==" " :
                liste.append(i)
                print(liste)
    et de s'en servir ensuite pour créer une nouvelle liste où on ajouterait les caractères de la phrase découpés selon les indices : par exemple
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    resultat+=phrase[2:6]
    resultat+=phrase[0:6]
    si l'espace se situe en indice 2 dans la phrase de départ ? par exemple "je veux" se verrait retourner "veux je" ?
    Bien sûr…
    Il suffit de construire une nouvelle liste par morceaux. Avec une variable intermédiaire qui "comptabilise" le nombre de mots (de 0 à 2) et une autre qui accumule ces mots à concurrence de 2…

    Clodion

  14. #14
    Membre averti
    Femme Profil pro
    Inscrit en
    Décembre 2013
    Messages
    21
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France

    Informations forums :
    Inscription : Décembre 2013
    Messages : 21
    Par défaut
    Merci,
    en fait je vois bien comment comptabiliser le nombre de mots mais je ne vois pas bien de quelle façon je dois ensuite me servir de cette information pour récréer ma nouvelle liste ?

  15. #15
    Membre émérite
    Homme Profil pro
    Aucune activité
    Inscrit en
    Novembre 2011
    Messages
    505
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Aucune activité

    Informations forums :
    Inscription : Novembre 2011
    Messages : 505
    Par défaut
    Bonsoir,

    Citation Envoyé par info-python Voir le message
    Merci,
    en fait je vois bien comment comptabiliser le nombre de mots mais je ne vois pas bien de quelle façon je dois ensuite me servir de cette information pour récréer ma nouvelle liste ?
    Il suffit de faire une bascule…
    Bon, rapidement, voilà ce que j'obtiens, cela semble fonctionner (on doit pouvoir faire nettement mieux!!!!!):

    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
    phrase = "Que j'aime à faire apprendre un nombre utile aux sages !\nImmortel Archimède, artiste ingénieur,"
     
    nv_phrase = ""      # phrase reconstruite
    nb_mots = 0         # compteur de mots
    grp_car = ""        # groupement de caractères en attente
    sep = " '"          # séparateurs de mots
     
    for car in phrase:  # boucle de parcours de phrase
        if car in sep:  # on est entre deux mots
            nb_mots += 1
        if nb_mots == 0:    # premier mot du groupe
            grp_car += car
        elif nb_mots == 1:  # deuxième mot du groupe
            if car in sep:
                grp_car = car + grp_car
            else:
                nv_phrase += car
        elif nb_mots == 2:  # deuxième mot terminé: inversion
            nb_mots = 0
            nv_phrase += grp_car + car
            grp_car = ""
     
    if len(grp_car)>0:
        nv_phrase += grp_car
        grp_car = ""
     
    print("_", phrase, "_", sep="")
    print("_", nv_phrase, "_", sep="")
    Sinon, il y a les directions indiquées par tyrtamos (transformer en premier lieu la chaîne de départ en liste de mots) et par YvDao (inverser les mots puis reconstituer la phrase) .

    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
    phrase = "Que j'aime à faire apprendre un nombre utile aux sages !\nImmortel Archimède, artiste ingénieur,"
     
    nv_phrase = ""
    mot = ""
    lst_mot = []
    sep = " '"
     
    for car in phrase:      # obtention d'une liste de mots
        if car in sep:
            lst_mot.append(mot)
            mot = ""
        else:
            mot += car
    if len(mot):            # s'il reste un mot en cours
        lst_mot.append(mot)
     
    for i in range(0, len(lst_mot)-1, 2):   # inversions des mots deux par deux (attention: dangereux)
        lst_mot[i], lst_mot[i+1] = lst_mot[i+1], lst_mot[i]
     
    for mot in lst_mot:     # reconstitution de la phrase
        if len(nv_phrase):  # éviter un séparateur en première position
            nv_phrase += sep[0]
        nv_phrase += mot
     
    print("_", phrase, "_", sep="")
    print(lst_mot)
    print("_", nv_phrase, "_", sep="")
    Clodion

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

    Voilà comment on pourrait faire:

    1ère fonction splitfn: renvoie les mots de la phrase un par un. L'avantage est que le séparateur peut être multiple: un ou plusieurs espaces, tabulations, fins de ligne, ... Et on peut changer la liste des séparateurs à l'appel de la fonction:

    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
    def splitfn(phrase, whitespace=[' ','\x09','\x0A','\x0D','\x0C','\x0B']):
        """renvoie un par un les mots de la phrase (séparateur = whitespace)"""
        i1, i2, lg = 0, 0, len(phrase)
        while True:
              # recherche des caractères de séparation
              while i2<lg and phrase[i2] in whitespace:
                    i2 += 1
              if i2>=lg:
                 break # fin de la chaine phrase
              i1 = i2
              # recherche du mot
              while i2<lg and phrase[i2] not in whitespace:
                    i2 += 1
              yield phrase[i1:i2] # renvoi du mot trouvé
              if i2>=lg:
                 break # fin de la chaine phrase
              i1 = i2
    2ème fonction inversion2a2: prend les mots renvoyés par la fonction précédente et les inverse dans la liste qui sera renvoyée à la fin. Pour cela, on suit l'évolution de l'index i, et on évalue si cet index est pair (i%2==0) ou non:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    def inversion2a2(phrase):
        """inversion des mots 2 à 2 (utilise splitfn)"""
        pile, liste = [], []
        for i, mot in enumerate(splitfn(phrase)):
            if i%2==0:
                pile.append(mot) # on empile le mot
            else:
                liste += [mot, pile.pop()] # on ajoute les 2 mots inversés à la liste
        if pile!=[]:
            liste += [pile.pop()] # au cas où le nombre total de mots serait impair
        return liste
    Exemple d'utilisation:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    phrase = "     Que j'aime à faire \r\n apprendre    un     nombre utile aux     sages  "
    liste = inversion2a2(phrase)
    print liste
    ["j'aime", 'Que', 'faire', 'à', 'un', 'apprendre', 'utile', 'nombre', 'sages', 'aux']
    Si la phrase possède un nombre impair de mots, le dernier mot est simplement ajouté à la liste. Voir s'il faut faire autrement.

Discussions similaires

  1. La méthode split
    Par JeuneJavaiste dans le forum Général JavaScript
    Réponses: 2
    Dernier message: 02/03/2009, 14h29
  2. Réponses: 4
    Dernier message: 10/04/2007, 16h26
  3. [C#2.0] méthode split avec séparateur de plusieurs caratères
    Par CUCARACHA dans le forum Windows Forms
    Réponses: 5
    Dernier message: 05/02/2007, 18h11
  4. Méthode Split
    Par Dlyan dans le forum MFC
    Réponses: 5
    Dernier message: 27/03/2006, 16h55
  5. Au sujet de la méthode split
    Par sylviefrfr dans le forum Langage
    Réponses: 6
    Dernier message: 17/11/2005, 13h24

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