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 :

Optimisation de code


Sujet :

Python

  1. #1
    Membre confirmé
    Homme Profil pro
    Technicien réseaux et télécoms
    Inscrit en
    Avril 2007
    Messages
    87
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 33
    Localisation : Belgique

    Informations professionnelles :
    Activité : Technicien réseaux et télécoms
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Avril 2007
    Messages : 87
    Par défaut Optimisation de code
    Bonjour, je suis actuellement le cours sur le Python et suite à un TP (5.8. Écrivez un script qui recopie une chaîne (dans une nouvelle variable), en insérant des astérisques entre les caractères.
    Ainsi par exemple, « gaston » devra devenir « g*a*s*t*o*n »), j'ai réalisé un code, il fonctionne mais j'aimerais savoir s'il y a moyen de l'optimiser et de le rendre plus propre.

    Le voici :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    chaine, nouvelle_chaine = "gaston7895", ""
    longueur = len(chaine)
    i = 0
     
    while i < longueur-1 :
    	nouvelle_chaine = nouvelle_chaine + chaine[i]+"*"
    	i=i+1
    nouvelle_chaine = nouvelle_chaine+chaine[longueur-1]
    print nouvelle_chaine
    Merci d'avance !

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

    Il y a une solution super simple:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    x = "gaston"
    y =  '*'.join(list(x))
    print y
    'g*a*s*t*o*n'
    Tyrtamos

  3. #3
    Membre confirmé
    Homme Profil pro
    Technicien réseaux et télécoms
    Inscrit en
    Avril 2007
    Messages
    87
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 33
    Localisation : Belgique

    Informations professionnelles :
    Activité : Technicien réseaux et télécoms
    Secteur : High Tech - Produits et services télécom et Internet

    Informations forums :
    Inscription : Avril 2007
    Messages : 87
    Par défaut
    Merci ! Je n'ai pas encore appris ça mais je le saurai pour la suite

  4. #4
    Membre Expert
    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
    Par défaut
    Bonjour,

    Bien sûr.

    Conseils:

    - une fois qu’on a trouvé une solution à un problème, le réexaminer en se disant:
    je suis sûr qu’il doit être possible de faire plus concis

    - si on arrive à faire plus concis, c’est souvent parce que Python dispose d’une fonction qui fait en un appel ce qu’on a fait avec plusieurs lignes de codes

    - pour trouver les fonctions sur les chaînes:
    http://www.python.org/doc/2.6.2/libr...html#index-585
    section 6.6.1

    J’aime bien aussi la présentation de la version 2.5
    http://www.python.org/doc/2.5.4/lib/...s.html#l2h-233

    - proverbe pythonien
    Ton code meilleure mine aura
    Toutes fois qu’indices élimineras


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    li = [23,56,34,67,56,35]
    k = 0
    while k<len(li):
        print li[k]
    c’est berk, alors qu’on peut faire


    Par ailleurs il y a déjà eu deux ou trois files sur ce problème, il sufit de faire une recherche.

  5. #5
    Expert confirmé
    Avatar de fred1599
    Homme Profil pro
    Lead Dev Python
    Inscrit en
    Juillet 2006
    Messages
    4 053
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations professionnelles :
    Activité : Lead Dev Python
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Juillet 2006
    Messages : 4 053
    Par défaut
    Un simple boucle for

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    for i in chaine: print i+"*",

  6. #6
    Membre émérite
    Avatar de Antoine_935
    Profil pro
    Développeur web/mobile
    Inscrit en
    Juillet 2006
    Messages
    883
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations professionnelles :
    Activité : Développeur web/mobile

    Informations forums :
    Inscription : Juillet 2006
    Messages : 883
    Par défaut
    Si le but est l'optimisation, des print consécutifs ne sont pas une bonne solution.
    Un print, c'est un appel système. Pour l'effectuer, il faut un context switch du processeur. De plus, selon le système d'exploitation, ça peut obliger aussi à sauvegarder tous les registres du processeur. Enfin, ça passe par un fichier (stdout), donc un buffer, donc des fonctions de contrôles.

  7. #7
    Membre Expert
    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
    Par défaut
    Merci Antoine935 pour ces explications.
    Je comprends enfin pourquoi l’affichage d’un grand nombre de courtes chaînes est long.


    Mais il y a un moyen de contourner le ralentissement: cumuler dans une seule chaîne plusieurs affichages courts.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    ch = 'gaston'
    mh = ch[0]
    for c in ch[1:]:
        mh += '*' + c
    print mh

    Application intéressante:
    afficher instantanément sous forme repr(ligne) les lignes d’un code source de site, ligne par ligne:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    import urllib
    sock = urllib.urlopen('http://www.partir.com/Equateur/Galapagos/')
    somt = ''
    for ln in sock:
        somt += '\n' + repr(ln)
    sock.close()
    print somt
    '<html>\n'
    '<head>\n'
    ' \n'
    "<title>Galapagos - Iles d'Equateur - tr\xe9sor de faune et flore</title>\n"
    ' <meta name="KeyWords" content="Equateur, Galapagos, Tourisme, voyage, Darwin, iguanes">\n'
    '</head>\n'
    '<Body BGColor="#FFFFFF" Link="#1580EA" VLink="#0A4075">\n'
    '\r\n'
    '\n'
    '\n'
    '\n'
    '\n'
    '<table>\n'
    ' <tr> \n'
    ' <td align=left>\n'
    '\n'
    '<script type="text/javascript"><!--\n'
    'google_ad_client = "pub-5608884666532582";\n'
    'google_ad_width = 728;\n'
    'google_ad_height = 90;\n'
    etc
    etc

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

    Petite défi-nette

    comment obtenir, sans expression régulière
    *c*h*o*c*o*l*a*t*
    à partir de
    chocolat?
    .

  8. #8
    Membre Expert
    Homme Profil pro
    Inscrit en
    Avril 2004
    Messages
    1 067
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Avril 2004
    Messages : 1 067
    Par défaut
    Citation Envoyé par eyquem Voir le message
    Petite défi-nette

    comment obtenir, sans expression régulière
    *c*h*o*c*o*l*a*t*
    à partir de
    chocolat?
    .
    j'comprends pas la question ....

  9. #9
    Expert confirmé
    Avatar de fred1599
    Homme Profil pro
    Lead Dev Python
    Inscrit en
    Juillet 2006
    Messages
    4 053
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations professionnelles :
    Activité : Lead Dev Python
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Juillet 2006
    Messages : 4 053
    Par défaut
    Il veut surement dire un truc de ce genre

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    >>> chaine="chocolat"
    >>> chaine="*".join(chaine)
    >>> chaine=list(chaine)
    >>> chaine.insert(0, "*")
    >>> chaine.insert(len(chaine)+1, "*")
    >>> for i in chaine: print i,
    ... 
    * c * h * o * c * o * l * a * t *

  10. #10
    Membre Expert
    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
    Par défaut
    Allons, allons...
    Tu t’es couché tard ce matin, fred1599 ?
    On ne peut pas insérer des caractères dans une chaîne, ni au milieu, ni devant, ni derrière, c’est entendu. Mais on peut concaténer des chaînes (catena = chaîne en latin):

    Tes lignes
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    chaine=list(chaine)
    chaine.insert(0, "*")
    chaine.insert(len(chaine)+1, "*")
    for i in chaine: print i,
    se remplacent par
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    chaine = '*'+chaine+'*'
    print chaine
    et même l'ensemble du code par
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    chaine = '*'+"*".join(chaine)+'*'
    print chaine
    ce qui évite la boucle for i in chaine: print i, dont Antoine935 a souligné l’horribilité.

    De plus, ta solution affiche des blancs entre les caractères.



    Soit dit en passant, avec
    chaine = ['*', 'c', '*', 'h', '*', 'o', '*', 'c', '*', 'o', '*', 'l', '*', 'a', '*', 't', '*']
    que tu obtiens,
    cette horreur de boucle print se remplace avantageusement par
    print "".join(chaine)
    join() est une fonction très très rapide







    Pour ce qui est de ma devinette, on peut obtenir *c*h*o*c*o*l*a*t*
    en une seule ligne, avec une certaine fonction, sans concaténation de chaînes évidemment.
    Et sans expression régulière; mais rien ne vous empêche de vous demander pourquoi je donne cette restriction.
    Je ne pratique pas les jeux vidéos, mais il doit bien y avoir dans ces jeux de semblables procédés pour détourner les intrépides quêteurs d'entrer dans les labyrinthes à deux portes.......

  11. #11
    Expert confirmé
    Avatar de fred1599
    Homme Profil pro
    Lead Dev Python
    Inscrit en
    Juillet 2006
    Messages
    4 053
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations professionnelles :
    Activité : Lead Dev Python
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Juillet 2006
    Messages : 4 053
    Par défaut
    J'avoue que je suis un peu fatigué, mais maintenant je suis en vacances, et donc je vais me retaper.


  12. #12
    Membre Expert
    Homme Profil pro
    Inscrit en
    Avril 2004
    Messages
    1 067
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Avril 2004
    Messages : 1 067
    Par défaut
    sans concatenation .... hummm, achement pas facile.

  13. #13
    Membre Expert
    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
    Par défaut
    sans concaténation , oui
    alors ? vas-y, dis. vas-y. vaaas-y: diiiis. vas-y !

    Je viens de penser à une solution avec deux fois join().
    Mais c'est possible avec une seule fois une fonction. Comment ?
    Je parle de ma devinette.

  14. #14
    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
    Et ça, ça va?

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    print '*'+'*'.join('chocolat')+'*'
    *c*h*o*c*o*l*a*t*
    Tyrtamos

    Edit: ah non, s'il ne faut pas de concaténation...

  15. #15
    Membre Expert
    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
    Par défaut
    Eh non, avec des + ça ne va pas.

    C’est artificiel comme devinette, mais c’est pas moi qu’ai commencé, c’est Swinnen.

    Rearquez, join() est une concaténation camouflée.
    Donc deux fois join(), ça ne va pas
    Alors j’y dis la solution avec deux fois join() :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    u = 'gaston'
    print '*'.join(u).join('**')
    Mais il y a une solution avec une seule fonction utilisée une seule fois qui fait ptêt bien de la concaténation cachée, mais on dirait qu’on ferait comme si c’était pas vrai.

  16. #16
    Membre émérite
    Avatar de Antoine_935
    Profil pro
    Développeur web/mobile
    Inscrit en
    Juillet 2006
    Messages
    883
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations professionnelles :
    Activité : Développeur web/mobile

    Informations forums :
    Inscription : Juillet 2006
    Messages : 883
    Par défaut
    Petite proposition, qui fait usage de ctypes, et ne fait aucune concaténation:
    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
    >>> from ctypes import create_string_buffer
    >>> 
    >>> def doStar(str):
    ...     l = len(str) * 2
    ...     b = create_string_buffer(l + 1)
    ...
    ...     for i in range(0, l, 2):
    ...         b[i] = '*'
    ...         b[i + 1] = str[i / 2]
    ...
    ...     b[l] = '*'
    ...
    ...     return b.value
    ...
    >>> doStar("chocolat")
    '*c*h*o*c*o*l*a*t*'

  17. #17
    Membre Expert
    Homme Profil pro
    Inscrit en
    Avril 2004
    Messages
    1 067
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Avril 2004
    Messages : 1 067
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    a = 'chocolat'
    dir(a)
    ['__add__', '__class__', '__contains__', '__delattr__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__getnewargs__', '__getslice__', '__gt__', '__hash__', '__init__', '__le__', '__len__', '__lt__', '__mod__', '__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__rmod__', '__rmul__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '_formatter_field_name_split', '_formatter_parser', 'capitalize', 'center', 'count', 'decode', 'encode', 'endswith', 'expandtabs', 'find', 'format', 'index', 'isalnum', 'isalpha', 'isdigit', 'islower', 'isspace', 'istitle', 'isupper', 'join', 'ljust', 'lower', 'lstrip', 'partition', 'replace', 'rfind', 'rindex', 'rjust', 'rpartition', 'rsplit', 'rstrip', 'split', 'splitlines', 'startswith', 'strip', 'swapcase', 'title', 'translate', 'upper', 'zfill']

    tiens, tiens, à quoi ça sert ça ..... ?
    essayons ...

    *c*h*o*c*ol*a*t*

    mouhahaha, j'ai trouvé.

  18. #18
    Membre Expert
    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
    Par défaut
    Eh bien, finalement, la question n’était pas si puérile puisqu’elle suscite des réponses intéressantes.


    josmiley . Pas tellement pour la réponse, mais pour la manière rationnelle de la trouver qui fait resortir l’intérêt de l’auto-documentation de Python à laquelle personnellement je ne pense pas assez.



    Antoine935, ça ne respecte pas la condition ’en une seule ligne“ que j’ai indiquée en #10, mais pour l’astuce de cette solution et l’aiguillon qu’elle constitue pour s’intéresser au module ctypes :



    Quant à moi j’ai trouvé cette solution ainsi:

    je me suis demandé comment ferait on avec les expressions régulières et j’ai pensé à la notion d’ «empty string» que j’ai mise longtemps à comprendre.

    Il se trouve que print re.sub('\B','*','gaston') marche, en ce sens que ça produit un effet, ça donne bien 'g*a*s*t*o*n'

    Mais print re.sub('\b','*','gaston') ne marche pas, parce que \b est en vérité définie comme limite entre \w et \W, la séquence spéciale \w étant équivalente à l’ensemble [a-zA-Z0-9_] et la seconde à [^a-zA-Z0-9_] . Or dans ’gaston’ g est bien \w mais il n’y a pas de \W devant.
    De ce fait on ne peut pas faire print re.sub(’\b|\B’,'*','gaston')

    Donc avec re, je n’y suis pas arrivé mais ça m’a fait penser à voir ce que ça donnerait avec replace().
    C’est pour ça que, dans mon idée, dire «sans expression régulière» consistait aussi bien à fermer une porte vers une possible solution qu’une piste pour entrer dans les expressions régulières et en resotir avec une idée.




    Bon, maintenant le problème est:
    comment transformer ’gaston’ en ’*g*a*s*t*o*n*’ avec une expression régulières et sub() ??

  19. #19
    Membre émérite
    Avatar de Antoine_935
    Profil pro
    Développeur web/mobile
    Inscrit en
    Juillet 2006
    Messages
    883
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations professionnelles :
    Activité : Développeur web/mobile

    Informations forums :
    Inscription : Juillet 2006
    Messages : 883
    Par défaut
    Elégante solution que celle de josmiley

    Citation Envoyé par eyquem Voir le message
    Antoine935, ça ne respecte pas la condition ’en une seule ligne“ que j’ai indiquée en #10
    Arf... avais pas vu cette règle
    Ca compte ça ?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    >>> str = "chocolat"
    >>> exec "l=len(str)*2;b=create_string_buffer(l+1);b[l]='*'\nfor i in range(0, l
    , 2):\n\tb[i]='*';b[i+1]=str[i/2]\nprint b.value"
    *c*h*o*c*o*l*a*t*
    comment transformer ’gaston’ en ’*g*a*s*t*o*n*’ avec une expression régulières et sub() ??
    De la même manière qu'avec replace ^^
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    re.sub("", "*", "gaston")

  20. #20
    Membre Expert
    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
    Par défaut
    Ah ben fichtre !! Qu’est ce que j’ai foutu dans le module re, moi ?
    Je crois que je m’y balade comme dans un dictionnaire, un vrai, genre Larousse: j’y entre pour un mot et j’en resors en ayant vu plein de mots sauf celui que je voulais regarder !





    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    exec "l=len(str)*2;b=create_string_buffer(l+1);b[l]='*'\nfor i in range(0, l
    , 2):\n\tb[i]='*';b[i+1]=str[i/2]\nprint b.value"
    Non, ça ne compte pas, il y a plus de 80 caractères.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. optimiser le code d'une fonction
    Par yanis97 dans le forum MS SQL Server
    Réponses: 1
    Dernier message: 15/07/2005, 08h41
  2. Optimiser mon code ASP/HTML
    Par ahage4x4 dans le forum ASP
    Réponses: 7
    Dernier message: 30/05/2005, 10h29
  3. optimiser le code
    Par bibi2607 dans le forum ASP
    Réponses: 3
    Dernier message: 03/02/2005, 14h30
  4. syntaxe et optimisation de codes
    Par elitol dans le forum Langage SQL
    Réponses: 18
    Dernier message: 12/08/2004, 11h54
  5. optimisation du code et var globales
    Par tigrou2405 dans le forum ASP
    Réponses: 2
    Dernier message: 23/01/2004, 10h59

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