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 :

Comment dédoubler une liste ou un string ?


Sujet :

Python

  1. #1
    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 Comment dédoubler une liste ou un string ?
    Je cherche à dédoubler une liste ou un string
    Exemple:
    l = [1, 5, 3] => ll = [1, 1, 5, 5, 3, 3]
    l = '153' => ll = '115533'

    L'objectif étant que ce soit le plus rapide possible (ma liste ou string initiale ayant une taille supérieur à 150000)

    Avec une méthode bourrine, je suis à 180ms pour la string et 210 ms pour la liste mais c'est beaucoup trop (il me faudrait ne pas dépasser les 50ms)
    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
     
    ## sur une string
    toto = 20000 * '1234567890'
    res = ''
    a = time.clock()
    for i in toto: res += i+i
    b = time.clock()
    print b-a
    ##sur une liste
    toto = 20000 * [1,2,3,4,5,6,7,8,9,0]
    res = []
    a = time.clock()
    for i in toto: 
        res.append(i)
        res.append(i)
     
    b = time.clock()
    print b-a

  2. #2
    Membre averti
    Inscrit en
    Février 2007
    Messages
    13
    Détails du profil
    Informations forums :
    Inscription : Février 2007
    Messages : 13
    Par défaut deoubler une liste
    s=[1,2,4,5,3,2,6]
    p=(s+s)
    p.sort()
    print p

    [1,1,2,2,2,2,3,3,4,4,5,5,6,6]
    c le minke tu peut faire

  3. #3
    Membre émérite
    Avatar de parp1
    Profil pro
    Inscrit en
    Mai 2005
    Messages
    829
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France, Calvados (Basse Normandie)

    Informations forums :
    Inscription : Mai 2005
    Messages : 829
    Par défaut
    Ouais mais la tu es tris....J'imagine que si c'est une image ... ce n'est pas compatible.

    Ca peut etre tres jolie.... mais ca s'arrete la.
    [SIZE="2"]Dis moi qui tu suis, je te dirais qui je Hais!
    Heureux est l'étudiant, qui comme la rivière suit son cours sans sortir de son lit

    Mon premier Tutoriel


    A 80% des cas je résouts mon problème en rédigeant une nouvelle discussion, du coup je ne poste que 20% de mes problèmes...

  4. #4
    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
    Effectivement, il s'agit d'une liste de valeur d'une image. Mais en y repensant, en fait, je ne récupère qu'une ligne sur 2 => donc je ne dois pas dédoubler chaque valeur de la liste mais chaque portion de la liste correspondant à une ligne, ce qui finalement va être beaucou plus rapide à traiter

  5. #5
    Membre émérite
    Avatar de parp1
    Profil pro
    Inscrit en
    Mai 2005
    Messages
    829
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France, Calvados (Basse Normandie)

    Informations forums :
    Inscription : Mai 2005
    Messages : 829
    Par défaut
    Eh je commence a le connaitre le _GuiGUI
    [SIZE="2"]Dis moi qui tu suis, je te dirais qui je Hais!
    Heureux est l'étudiant, qui comme la rivière suit son cours sans sortir de son lit

    Mon premier Tutoriel


    A 80% des cas je résouts mon problème en rédigeant une nouvelle discussion, du coup je ne poste que 20% de mes problèmes...

  6. #6
    Membre éprouvé
    Profil pro
    Inscrit en
    Octobre 2004
    Messages
    89
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2004
    Messages : 89
    Par défaut petites optimisations testées avec 2.4
    bonsoir tout d'abord deux petites choses :

    en ce qui concerne les mesures :
    il vaut mieux les effectuer plusieurs fois, on obtient ainsi quelque chose de plus cohérent et beaucoup moins dépendant du reste de l'ordi.

    Pour le code :
    il n'est pas normal que l'utilisation d'une liste soit plus longue que l'utilisation d'une string.
    En effet une string est une sequence immuable, donc le fait de faire s+='new character' entraine obligatoirement la création d'une nouvelle séquence.

    Ton souci est au niveau de ton code :
    le fait d'écrire res.append à l'intérieur d'une boucle (ici un for) n'est vraiment pas bon pour les performances, car la liste 'res' est réévaluée à chaque itération !
    Il faut absolument utiliser un alias tel que alias = res.append et dans ton for
    alias(i)

    Bon la preuve en image de tout ce que je raconte au dessus :
    fichier to_test.py
    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
    t_s = 20000 * '1234567890'
    t_l = 20000 * [1,2,3,4,5,6,7,8,9,0]
     
     
    def t_string(seq=t_s):
        res = ''
        for i in seq:
            res += i+i
        return res
     
    def t_list_without_alias(seq=t_l):
        res = []
        for i in seq:
            res.append(i)
            res.append(i)
        return res
     
    def t_list_with_alias(seq=t_l):
        res = []
        alias=res.append
        for i in seq:
            alias(i)
            alias(i)
        return res
    et un petit module testeur.py utilisant le module timit.
    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
    import timeit
     
    module='to_test'
    f = module + '.t_list_with_alias()'
    f1 = module + '.t_string()'
    f2 = module + '.t_list_without_alias()'
     
    def footime(s, m=module, n=1):
        t = timeit.Timer(s, 'import %s ; reload(%s); gc.enable()' %(m,m))
        time = t.timeit(n)
        return time
     
    print f, footime(f,n=10)
    print f1, footime(f1,n=10)
    print f2, footime(f2,n=10)
    Comme tu le vois l'execution de ce module demande d'executer 10 fois chaque fonction afin d'avoir un résultat plus cohérent comme expliqué plus haut.
    Voici les résultats d'exécution sur ma machine.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    to_test.t_list_with_alias() 1.02240005364
    to_test.t_string() 1.15563346738
    to_test.t_list_without_alias() 1.80934196944
    Ils confirment les explications données plus haut.

    @++

  7. #7
    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
    Effectivement, j'avais oublié d'utiliser les alias, ce qui fait que travailler sur les listes est bien plus intéressant. Dans mon cas, ce sera plutôt avec extend.
    Pour la timeit, j'ai tendance à me contenter du time.clock() qui est largement suffisant pour avoir un ordre d'idée.

    Au final, voilà le traitement que je fais, je récupère une image sous forme de chaine de caractères ne comprenant qu'une ligne sur 2, il me faut donc dédoubler chaque ligne et transformer chaque chaine en son équivalent nombre ascii pour reconstituer entièrement mon image. Je pense que je me contenterai donc de cette méthode (ce qui prend du temps, c'est plus le map mais les temps de traitement me satifsont à peu près maintenant ).

    a.py
    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
    seq = 18900 * '1234567890'
     
    def teststring(toto = seq):
        res = ''
        for i in range(270):
            res += 2 * toto[700*i:700*i+700]
        l1 = map(ord, res)
        return l1
     
    def testlist(toto = seq):
        ll = map(ord, toto)
        l2 = []
        l2e = l2.extend
        for i in range(270):
            l2e(ll[700 * i:700 *i+700])
            l2e(ll[700 * i:700 *i+700])
        return l2

    to_test.py:
    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
    import timeit
     
    fs = 'a.teststring()'
    fl = 'a.testlist()'
     
     
    def footime(s, m = 'a', n=1):
        t = timeit.Timer(s, 'import %s ; reload(%s); gc.enable()' %(m,m))
     
        time = t.timeit(n)
        return time
     
    print 'teststring', footime(fs, n=50)
    print 'testlist', footime(fl, n=50)
    raw_input("")

    =>
    teststring 3.95264286383
    testlist 3.56019298542
    Au final, ca fait quand même 10% d'écart, c'est toujours cela de gagner.

    En tout cas, merci à tous.

    Edit: En fait, je n'avais pas du tout penser qu'on pouvait créer une image à partir d'une chaine de caractère (les données étant récupérées sous forme de nombre ascii) avec la fonction Image.fromstring(...). Donc mon problème du map est résolu et maintenant, j'ai enfin des temps qui me convienne parfaitement.

  8. #8
    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 en revenir à la méthode avec les string, il est plus intéressant de construire une liste avec les string puis de la concaténer avec la méthode join

    à rajouter dans to_test.py
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    def t_stringlist(seq=t_s):
        l = []
        la = l.append
        for i in seq:
            la(i)
            la(i)
        return ''.join(l)
    dans testeur.py
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    f3 = module + '.t_stringlist()'
    print f3, footime(f3,n=10)

    Resultat:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    to_test.t_list_with_alias() 0.80733528982
    to_test.t_string() 1.04854918712
    to_test.t_list_without_alias() 1.50495859111
    to_test.t_stringlist() 0.925189095262

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

Discussions similaires

  1. comment slicer une liste de strings?
    Par wakka123 dans le forum Général Python
    Réponses: 5
    Dernier message: 09/04/2012, 11h21
  2. [Vb.net] Comment faire une liste à partir d'une string
    Par NicoNGRI dans le forum ASP.NET
    Réponses: 1
    Dernier message: 25/10/2006, 14h15
  3. Réponses: 5
    Dernier message: 29/09/2005, 14h37
  4. Comment initialiser une liste de composants avec une boucle ?
    Par EricSid dans le forum Composants VCL
    Réponses: 5
    Dernier message: 06/04/2005, 18h46
  5. [PDFBox]Comment manipuler une LIST
    Par marcotop dans le forum Documents
    Réponses: 11
    Dernier message: 27/08/2004, 15h46

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