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 :

Compter le nombre de ligne d'un fichier sans le lire


Sujet :

Python

  1. #1
    Futur Membre du Club
    Profil pro
    Inscrit en
    Octobre 2007
    Messages
    22
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2007
    Messages : 22
    Points : 8
    Points
    8
    Par défaut Compter le nombre de ligne d'un fichier sans le lire
    Bonjour à tous,

    Après quelques recherches sur le net et sur le forum je n'ai pas trouvé de réponse à ma question.

    J'ai un fichier toto.xml dont je veux compter le nombre de lignes pour connaitre la fin de mon fichier.

    Avec mes connaissances je sais faire :

    fic=open('toto.xml', 'r')
    lecture = fic.readlines()
    N_lignes = len(lecture)
    fic.close()

    Mais j'aimerai compter ce nombre de lignes sans avoir à lire le fichier car charger le fichier en mémoire avec le readlines() c'est long si le fichir est gros !

    Si vous avez une idée ou une piste à me donner je suis preneur

    Merci

    ffets

    PS : mon titre est un peu nul mais j'n'ai pas trouvé mieux :S

  2. #2
    Membre éprouvé

    Profil pro
    Inscrit en
    Août 2004
    Messages
    723
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2004
    Messages : 723
    Points : 923
    Points
    923
    Par défaut
    Impossible sans lire, par contre au lieu de faire par readlines qui est lourd pour la mémoire si le fichier est gros, tu peux soit faire ça en dur (recherche de tous les retours à la ligne en cherchant caractère par caractère) soit compter les itérations d'une boucle for sur le fichier:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    fd = open('toto.xml', 'r')
    n = 0
    for line in fd:
        n += 1

  3. #3
    Futur Membre du Club
    Profil pro
    Inscrit en
    Octobre 2007
    Messages
    22
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2007
    Messages : 22
    Points : 8
    Points
    8
    Par défaut
    Citation Envoyé par oiffrig Voir le message
    soit compter les itérations d'une boucle for sur le fichier:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    fd = open('toto.xml', 'r')
    n = 0
    for line in fd:
        n += 1
    Ok merci de l'info. C'est en effet d'une telle boucle for que je parlais dans mon post. Donc s'il n'y a pas mieux ça me rassure je ne fais pas que des trucs nuls !!

    Merci
    A+
    ffets

  4. #4
    Membre extrêmement actif
    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
    Points : 1 658
    Points
    1 658
    Par défaut il y a une autre façon de faire
    que j'ai vue là: http://www.developpez.net/forums/d61...-fichier-trie/

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    fd = open('toto.xml', 'r')
    n = 0
    while fd.readline():
        n += 1

    Quelle avantage/inconvenient par rapport a ? :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    fd = open('toto.xml', 'r')
    n = 0
    for line in fd:
        n += 1
    Il me semble que dans les deux cas ça lit les lignes du fichier une par une. Je ne vois pas ce qui pourrait se passer d'autre.

  5. #5
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Avril 2008
    Messages
    30
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2008
    Messages : 30
    Points : 25
    Points
    25
    Par défaut
    Bonjour,
    je ne peux pas dire quelles sont les avantages et inconvénients de l'une et de l'autre mais en faisant un test très simple (prendre un gros fichier (le mien fait 90Mo) histoire de voir réellement une différence)

    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 profile,time
     
     
    def func1():
    	fd = open("d:\\python\\bpss.txt", 'r')
    	n = 0
    	while fd.readline():
    		n += 1
     
    def func2():
    	fd = open("d:\\python\\bpss.txt", 'r')
    	n = 0
    	for line in fd:
    		n += 1
     
     
    time_dep=time.time()
    func1()
    print time.time()-time_dep
    time_dep=time.time()
    func2()
    print time.time()-time_dep
    profile.run("func1()")
    profile.run("func2()")

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    D:\python>python d:\python\new23.py
    3.01699995995
    1.28200006485
     
    D:\python>python d:\python\new23.py
    2.76700019836
    1.28199982643
     
    D:\python>python d:\python\new23.py
    2.76800012589
    1.28200006485
    on s'aperçoit que sur un gros fichier (plus de deux millions de lignes) la différence est de 1.5sec, la boucle "while fd.readline():" est donc plus rapide que la boucle "for line in fd:" mais sur des fichiers de taille normal je dirais que l'un équivaut à l'autre


    Après évidement il y a surement des cas ou l'on préférera l'un à l'autre mais je ne suis pas assez calé pour répondre.

    M.L.G.

  6. #6
    Membre éclairé
    Avatar de GnuVince
    Profil pro
    Développeur informatique
    Inscrit en
    Avril 2004
    Messages
    679
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Avril 2004
    Messages : 679
    Points : 803
    Points
    803
    Par défaut
    Une façon que j'aime pour compter le nombre de lignes (peut-être pas aussi rapide qu'une boucle for par contre):

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    n = sum(1 for _ in open('/etc/passwd'))

  7. #7
    Membre extrêmement actif
    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
    Points : 1 658
    Points
    1 658
    Par défaut Compar-hatif
    la boucle "while fd.readline():" est donc plus rapide que la boucle "for line in fd:"
    C'est le contraire.

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

    J'ai complété le programme pour comparer 4 méthodes.

    Comme je trouvais bizarre de faire appel a time() qui, pour autant que j'ai bien compris, va chercher le temps dans l'horloge de l'ordinateur et non pas dans le processeur ( c'est bien ça ??????),
    je fais la comparaison une fois en utilisant time() pour la mesure des durées, et une autre fois avec clock(). Je ne constate pas de différence notable entre l'utilisation de time() et celle de clock().
    En fait, time() ou clock(), ce n'est pas assez précis pour des processus tournant aussi vite.

    Sur un fichier de 16 MB ça donne comme résultats:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     nombre de tours :  4
     
     
                       fd.readline()     for _ in open     line in fd        count('\n')      
     
    avec time()        2.66874998808     1.07150000334     0.98400002718     0.898750007153
    nb de lignes       363376            363376            363376            363376
     
    avec clock()       2.68206049931     1.07953915931     1.00368706079     0.977146117733
    nb de lignes       363376            363376            363376            363376
    La différence entre line in fd et count('\n') n'est pas flagrante mais ces deux méthodes sont plus rapides que les 2 autres.



    Mais pour un fichier de 46 MB, les résultats sont:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     nombre de tours :  4
     
     
                       fd.readline()     for _ in open     line in fd        count('\n')      
     
    avec time()        7.77124994993     3.17949998379     2.95674997568     10.1220000386
    nb de lignes       996699            996699            996699            996699
     
    avec clock()       7.88368465825     3.20289010195     2.93485051871     7.29113211316
    nb de lignes       996699            996699            996699            996699

    Il doit bien y avoir une différence entre fd.readline() et line in fd puisque le temps d'exécution avec fd.readline() varie selon la taille du fichier.
    C'est aussi le cas pour la méthode avec count('\n') . Celle ci est la plus rapide si le fichier est petit mais pas tellement plus rapide que la méthode avec line in fd.
    Et c'est cette dernière méthode avec line in fd dont le temps d'exécution varie le moins.


    La méthode d'une rapidité élevée et stable est avec line in fd

    Mais la méthode avec for _ in open est à peine moins rapide et elle remporte la palme sur la base des deux critères rapidité ET concision.
    Bravo GnuVince.

  8. #8
    Membre extrêmement actif
    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
    Points : 1 658
    Points
    1 658
    Par défaut j'ai oublié
    Mon programme de comparaison des temps d'execution
    Il sort des temps moyens sur nb_essais reiterations

    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
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    from time import clock, time
     
    nb_essais = 4
    nom = raw_input('\n Entrer le nom du fichier : ')
     
    def func1():
            k = 0
            while k<nb_essais:
                    fd = open(nom, 'r')
                    n = 0
                    while fd.readline():
                            n += 1
                    fd.close()
                    k+=1
            return n
     
    def func2():
            k = 0
            while k<nb_essais:
                    n = sum(1 for _ in open(nom))
                    k+=1
            return n
     
     
    def func3():
            k = 0
            while k<nb_essais:
                    fd = open(nom, 'r')
                    n = 0
                    for line in fd:
                            n += 1
                    fd.close()
                    k+=1
            return n
     
     
    def func4():
            k = 0
            while k<nb_essais:
                    fd = open(nom, 'r')
                    lu = fd.read()
                    n = lu.count('\n')
                    fd.close()
                    k+=1
            return n
     
     
     
     
    print '\n nombre de tours : ',nb_essais
    print "\n\n                   fd.readline()     for _ in open     line in fd        count('\\n')      "
    print
     
     
    print 'avec time()       ',
     
    time_dep=time()
    n1 = func1()
    print (time()-time_dep)/nb_essais,'   ',
     
    time_dep=time()
    n2 = func2()
    print (time()-time_dep)/nb_essais,'   ',
     
    time_dep=time()
    n3 = func3()
    print (time()-time_dep)/nb_essais,'   ',
     
    time_dep=time()
    n4 = func4()
    print (time()-time_dep)/nb_essais
     
     
    print 'nb de lignes      ',n1,'          ',n2,'          ',n3,'          ',n4
    print
     
     
     
    print 'avec clock()      ',
     
    t1=clock()
    n1 = func1()
    print (clock()-t1)/nb_essais,'   ',
     
    t2=clock()
    n2 = func2()
    print (clock()-t2)/nb_essais,'   ',
     
    t3=clock()
    n3 = func3()
    print (clock()-t3)/nb_essais,'   ',
     
    t4=clock()
    n4 = func4()
    print (clock()-t4)/nb_essais
     
    print 'nb de lignes      ',n1,'          ',n2,'          ',n3,'          ',n4
    print

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

Discussions similaires

  1. Réponses: 9
    Dernier message: 03/06/2007, 10h53
  2. Compter le nombre de ligne dans un fichier
    Par amine_en_france dans le forum Scripts/Batch
    Réponses: 2
    Dernier message: 31/05/2007, 17h19
  3. Compter le nombre de lignes d'un fichier ?
    Par [ZiP] dans le forum Delphi
    Réponses: 5
    Dernier message: 22/03/2007, 14h08
  4. Compter le nombre de lignes d'un fichier excel
    Par Freerideuse dans le forum Macros et VBA Excel
    Réponses: 2
    Dernier message: 06/07/2006, 21h49
  5. Réponses: 2
    Dernier message: 02/03/2004, 19h38

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