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 :

Remplacer un mot dans une liste comme en LISP


Sujet :

Python

  1. #1
    Nouveau Candidat au Club
    Femme Profil pro
    Étudiant
    Inscrit en
    Février 2016
    Messages
    6
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Février 2016
    Messages : 6
    Points : 1
    Points
    1
    Par défaut Remplacer un mot dans une liste comme en LISP
    Bonjour ,
    Je suis bloqué sur une fonction en Python je n'arrive pas à comprendre où se trouve mon erreur.
    Je dois créer une fonction en python qui remplace un mot par un autre lorsqu'on le trouve dans une liste. Pour tester les fonctions j'ai décidé de remplacer le mot "chat" par le mot "chien" .

    Le but de l'exercice était de reprendre une fonction que j'ai faite en LISP, de la traduire en C, puis en Python. Mais pour celle en Python je ne comprends pas pourquoi seulement la première occurrence du mot est traitée:

    Voici ma fonction :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    def remplace(L, toto, tata) :
      if not L : return None
      if L[0] == toto : L[0] = tata            #si (car L) == toto je le remplace par tata
      return remplace(L[1:], toto, tata)    #je passe à la suite de la liste (cdr L)
    Test de la fonction:

    >L = ['chat', 'loup', 'pieuvre', 'chat', 'loutre', 'rat']

    > remplace(L, "chat", "chien")
    > L
    ['chien', 'loup', 'pieuvre', 'chat', 'loutre', 'rat']


    Merci beaucoup pour votre aide.

  2. #2
    Membre expérimenté Avatar de plxpy
    Homme Profil pro
    Ingénieur géographe
    Inscrit en
    Janvier 2009
    Messages
    792
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 59
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Ingénieur géographe
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Janvier 2009
    Messages : 792
    Points : 1 481
    Points
    1 481
    Par défaut
    Bonjour
    Ton erreur est à la ligne 4 : L[1:] est une nouvelle liste. Tu ne changeras jamais que le premier élément (s'il vaut toto) en t'y prenant de la sorte.
    Là, dans tes tests, tu as déjà eu de la chance ! Essaye de changer "loup" en ce que tu veux : ta liste ne changera même pas.
    "La simplicité ne précède pas la complexité, elle la suit." - Alan J. Perlis
    DVP ? Pensez aux cours et tutos, ainsi qu'à la FAQ !

  3. #3
    Expert éminent

    Homme Profil pro
    Inscrit en
    Octobre 2008
    Messages
    4 300
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations forums :
    Inscription : Octobre 2008
    Messages : 4 300
    Points : 6 780
    Points
    6 780
    Par défaut
    Salut,

    En général on ne convertit pas du code entre des langages aussi différent en espérant qu'un mimétisme syntaxique suffira.

    Chance si ça marche.

    Dans ton cas tu peux itérer sur les termes de la liste.

    Si tu dois conserver la liste:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    >>> def replace_(items, old, new):
    ...     for idx, i in enumerate(items):
    ...             if i == old:
    ...                     items[idx] = new
    ... 
    >>> replace_(L, 'chat', 'chien')
    >>> L
    ['chien', 'loup', 'pieuvre', 'chien', 'loutre', 'rat']
    Si tu veux une autre liste:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    >>> def replace_(items, old, new):
    ...     return [i.replace(old, new) for i in items]
    ... 
    >>> L2 = replace_(L, 'chat', 'chien')
    >>> L2
    ['chien', 'loup', 'pieuvre', 'chien', 'loutre', 'rat']

  4. #4
    Nouveau Candidat au Club
    Femme Profil pro
    Étudiant
    Inscrit en
    Février 2016
    Messages
    6
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Février 2016
    Messages : 6
    Points : 1
    Points
    1
    Par défaut
    Je viens de faire un test en accédant directement à la deuxième occurrence de 'chat' comme le ferait la fonction. Effectivement ça ne fonctionne pas du tout.
    Il n'y a donc pas de solution pour que la fonction REMPLACE fonctionne correctement en utilisant L[1:] comme paramètre?


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    >>> L
    ['chat', 'loup', 'pigeon', 'chat', 'pierre', 'ciseaux']
     
    > L[3:][0] == 'chat'       
    True
     
    > L[3:][0] = 'chien'      
    > L
    ['chat', 'loup', 'pigeon', 'chat', 'pierre', 'ciseaux']

  5. #5
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 287
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 287
    Points : 36 776
    Points
    36 776
    Par défaut
    Salut,

    Citation Envoyé par As_Myers Voir le message
    Il n'y a donc pas de solution pour que la fonction REMPLACE fonctionne correctement en utilisant L[1:] comme paramètre?
    Il n'est pas interdit de faire que replace retourne une nouvelle liste (plutôt que d'essayer de modifier la liste "in place").
    Une autre solution serait d'ajouter l'indice de début à traiter comme paramètre.
    Mais comme vous programmez en Python et non en Lisp, une boucle "for" serait tout aussi bien.

    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  6. #6
    Nouveau Candidat au Club
    Femme Profil pro
    Étudiant
    Inscrit en
    Février 2016
    Messages
    6
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Février 2016
    Messages : 6
    Points : 1
    Points
    1
    Par défaut
    Citation Envoyé par VinsS Voir le message
    En général on ne convertit pas du code entre des langages aussi différent en espérant qu'un mimétisme syntaxique suffira.
    J'aimerai bien faire autrement mais le déplacement dans la liste doit se faire comme en LISP, je dois donc éviter les boucles. Vous pouvez voir si dessous deux fonctions que j'ai faite en suivant cette consigne.


    En Lisp
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    (defun occurences (L toto) 
      (cond
      ((not L) 0)
      ((string= (car L) toto) (1+ (occurences (cdr L) toto))) 
      ((occurences (cdr L) toto)) ) )

    Puis en PYTHON
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    def occurences(L, toto) :
      if not L : return 0
      if L[0] == toto : return 1 + occurences(L[1:], toto)
      return occurences(L[1:], toto)

  7. #7
    Nouveau Candidat au Club
    Femme Profil pro
    Étudiant
    Inscrit en
    Février 2016
    Messages
    6
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Février 2016
    Messages : 6
    Points : 1
    Points
    1
    Par défaut
    Citation Envoyé par wiztricks Voir le message
    Il n'est pas interdit de faire que replace retourne une nouvelle liste (plutôt que d'essayer de modifier la liste "in place").
    Une autre solution serait d'ajouter l'indice de début à traiter comme paramètre.

    Je pense essayer ces deux solutions, merci à tous pour votre aide, le plus important était que je comprenne mon erreur et c'est chose faite

  8. #8
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 287
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 287
    Points : 36 776
    Points
    36 776
    Par défaut
    Citation Envoyé par As_Myers Voir le message
    J'aimerai bien faire autrement mais le déplacement dans la liste doit se faire comme en LISP, je dois donc éviter les boucles. Vous pouvez voir si dessous deux fonctions que j'ai faite en suivant cette consigne.
    Lorsque vous écrivez:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    for x in range(len(L)):
         if L[x] == ...
    vous balayez la liste du premier au dernier élément.

    Pire comme L[1:] construit une nouvelle liste à chaque appel, vous ne vous déplacez plus du tout dans la liste...

    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  9. #9
    Expert éminent

    Homme Profil pro
    Inscrit en
    Octobre 2008
    Messages
    4 300
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations forums :
    Inscription : Octobre 2008
    Messages : 4 300
    Points : 6 780
    Points
    6 780
    Par défaut
    Citation Envoyé par As_Myers Voir le message
    ... je dois donc éviter les boucles
    Lorsque tu fais:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    def occurences(L, toto) :
      if not L : return 0
      if L[0] == toto : return 1 + occurences(L[1:], toto)
      return occurences(L[1:], toto)
    Tu boucles sur la fonction elle-même.

  10. #10
    Nouveau Candidat au Club
    Femme Profil pro
    Étudiant
    Inscrit en
    Février 2016
    Messages
    6
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Février 2016
    Messages : 6
    Points : 1
    Points
    1
    Par défaut
    Quand je disais devoir éviter les boucles je voulais dire éviter d'introduire des boucles de type for ou while dans la fonction, mais je dois bien boucler sur la fonction elle même.

    Je n'ai pas encore réussi à ajouter l'indice du début de la liste à traiter comme paramètre de la fonction comme l'a suggéré wiztricks mais j'ai fait en sorte que la fonction remplisse une nouvelle liste.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    L = ['loup', 'chat', 'chat', 'chat', 'chat', 'rat']
    L2 = []
     
    def remplace(L, old, new) :
        if not L : return None
        if L[0] == old : L2.append(new)
        else : L2.append(L[0])
         remplace(L[1:], old, new)
     
     
    >remplace(L, "chat", "chien")
    >L2
    ['loup', 'chien', 'chien', 'chien', 'chien', 'rat']

  11. #11
    Expert éminent

    Homme Profil pro
    Inscrit en
    Octobre 2008
    Messages
    4 300
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations forums :
    Inscription : Octobre 2008
    Messages : 4 300
    Points : 6 780
    Points
    6 780
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    L2 = []
     
    def remplace(L, old, new) :
        if not L : return None
        if L[0] == old : L2.append(new)
        else : L2.append(L[0])
         remplace(L[1:], old, new)
    Nous appelons cela "définitivement anti-pythonique".

  12. #12
    Nouveau Candidat au Club
    Femme Profil pro
    Étudiant
    Inscrit en
    Février 2016
    Messages
    6
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Février 2016
    Messages : 6
    Points : 1
    Points
    1
    Par défaut
    Citation Envoyé par VinsS Voir le message
    Nous appelons cela "définitivement anti-pythonique".
    On est d'accord, mais c'est ce que l'on me demande de faire... Ça doit vous piquer les yeux

  13. #13
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 287
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 287
    Points : 36 776
    Points
    36 776
    Par défaut
    Citation Envoyé par As_Myers Voir le message
    On est d'accord, mais c'est ce que l'on me demande de faire... Ça doit vous piquer les yeux
    En Lisp (et en Python), on évite les variables globales.
    On écrit donc plutôt cela ainsi:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    >>> def replace(alist, old, new):
    ...     if alist:
    ...        w = alist[0] if alist[0] != old else new
    ...        return [ w ] + replace(alist[1:], old, new)
    ...     return []
     
    >>> L = ['loup', 'chat', 'chat', 'chat', 'chat', 'rat']
    >>> replace(L, 'chat', 'chien')
    ['loup', 'chien', 'chien', 'chien', 'chien', 'rat']
    >>> replace(L, 'rat', 'chien')
    ['loup', 'chat', 'chat', 'chat', 'chat', 'chien']
    >>>
    Et si on est branché côté compréhension de liste:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    >>> def replace(alist, old, new):
    ...     return [ w.replace(old, new) for w in alist ]
    ...
    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

Discussions similaires

  1. Réponses: 9
    Dernier message: 23/12/2013, 16h40
  2. Comment remplacer un mot dans une chaines de caractere?
    Par lakhdharani dans le forum Débuter avec Java
    Réponses: 2
    Dernier message: 24/02/2009, 11h58
  3. Réponses: 0
    Dernier message: 13/03/2008, 08h51
  4. remplacer un mot dans une ligne
    Par italiasky dans le forum Shell et commandes GNU
    Réponses: 12
    Dernier message: 08/04/2007, 19h19

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