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 :

Traitement d'un fichier txt


Sujet :

Python

  1. #1
    Membre averti
    Profil pro
    Étudiant
    Inscrit en
    Mai 2009
    Messages
    50
    Détails du profil
    Informations personnelles :
    Âge : 35
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mai 2009
    Messages : 50
    Par défaut Traitement d'un fichier txt
    Bonjou tout le monde.

    J'avais posté hier un sujet pour la traitement d'un fichier XL, mais ca a été plus compliqué que prévu.

    Donc j'ai eu l'idée de le tableau de deux colonnes en plusieurs lignes, dont les données sont séparée par des ';'.

    Pour ceux qui ne connaissent pas le tableau (lignes). Chaque ligne contient un id de l'élève ainsi que son nom.


    Donc je cherche maitenant un programme qui me permet d'afficher le nom de l'élève pour chaque client, et c'est tout. Sans oublier de ne pas prendre la première ligne en compte, car elle contient le titre du document.

    Merci d'avance

  2. #2
    Membre émérite
    Homme Profil pro
    Inscrit en
    Décembre 2007
    Messages
    758
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France

    Informations professionnelles :
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Décembre 2007
    Messages : 758
    Par défaut
    bonjour,

    Citation Envoyé par anass_59 Voir le message
    afficher le nom de l'élève pour chaque client, et c'est tout
    afficher le nom de l'élève je comprends, mais ça veut dire quoi "pour chaque client" ?

  3. #3
    Membre averti
    Profil pro
    Étudiant
    Inscrit en
    Mai 2009
    Messages
    50
    Détails du profil
    Informations personnelles :
    Âge : 35
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mai 2009
    Messages : 50
    Par défaut
    Oups faute d'innatention

    Je voulais dire pour chaque id ...

  4. #4
    Membre confirmé
    Profil pro
    Inscrit en
    Septembre 2008
    Messages
    105
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2008
    Messages : 105
    Par défaut
    Bonjour,

    Ca, je connais, je suis en plein dedans...
    Mon fichier texte, je lui ai affecté une extension non pas en .txt, mais en .csv que j'ouvre avec mon tableur qui me propose comme séparateur par défaut la vigule.
    Si tu as choisi le ; c'est pas un problème, tu le signales à l'ouverture.

    Ce que j'ai fait (en mode très naïf : j'apprendrai donc bcp des autres réponses), par exemple pour la création :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    n = nb de lignes de donnees
    fichier=open('ASSR.csv','w')
    L=[['Dupont','07175'],['DURAND','06124']...]
    titre='Identite,Numero'+'\n'
    fichier.write(titre)
    for j in range(n):
        ligne=L[j,0]+','+L[j,1]+'\n'
        fichier.write(ligne)
    fichier.close()
    Reste deux problèmes :
    1. Liste ordonnée ou pas ?
    Donc problème de tri...
    Que j'ai résolu comme ça (encore naïvement) :
    L=['Dupont_07175','DURAND_06124',..]
    (avec des noms tous du même nombre de caractères)
    L.sort()
    puis j'ai séparé les enregistrements en 2, via unsc=L.find('_')
    et restocké le tout.
    Il y a aussi :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    >>> L=[('c', 2), ('d', 1), ('a', 4), ('b', 3) ]
    >>> L.sort(lambda a, b: cmp(a[0], b[0]))
    >>> L
    [('a', 4), ('b', 3), ('c', 2), ('d', 1) ]
    mais je ne sais plus pourquoi, ça ne m'allait pas..

    2 Le nom du dossier courant
    Résolu en utilisant l'import de glob et de getcwd
    rep=getcwd() donne le nom du répertoire courant
    puis fichier=open(rep+chr(92)+'ASSR.csv','w')
    chr(92) : \

    Pour la lecture :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    fichier=open('ASSR.csv','r')
    L=fichier.readlines()
    n=len(L)
    for j in range(n):
        ligne=L[j]
        print ligne,
    @+

  5. #5
    Membre émérite
    Homme Profil pro
    Inscrit en
    Décembre 2007
    Messages
    758
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France

    Informations professionnelles :
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Décembre 2007
    Messages : 758
    Par défaut
    il existe un module dédié python pour les fichier csv:

    http://docs.python.org/library/csv.html

    plutôt qu'une liste de liste, j'aurais plutôt mis une liste de tuples:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    L=[(7175,'Dupont'),(6124,'DURAND')...]
    du coup, on peut facilement trier par id croissant:
    si on veut trier par ordre alphabétique, on peut remplacer le tuple (id,name) par (name,id).

    l'écriture devient (en utilisant l'itérateur des listes, c'est mieux que de passer par range ou xrange ):

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    for (name,id) in L:
        fichier.write("%i,%s\n" % (id,name))
    attention à ne pas utiliser chr(92) qui n'est pas portable mais plutôt os.sep.

    pour la lecture, je préfère aussi utiliser l'itérateur du fichier (plus concis et en cas de gros fichier on encombre pas la mémoire avec readlines):

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    fichier=open('ASSR.csv','r')
    for ligne in fichier:
        print ligne,

  6. #6
    Membre confirmé
    Profil pro
    Inscrit en
    Septembre 2008
    Messages
    105
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2008
    Messages : 105
    Par défaut
    Bonjour,

    Intéressant !
    Pas pensé à la liste de tuples...
    Pas pensé à for ligne in fichier
    anass_59 semble n'avoir qu'un fichier à traiter à la fois.
    Moi, j'en gère 6, ouverts simultanément,de longueurs différentes pour en faire un 7e, alors je vais voir comment adapter tes suggestions...
    Y a-t-il un moyen de connaître la longueur d'un fichier sans le charger ?

    Je ne pollue pas plus longtemps le topic de anass_59

    Merci,

    @+

  7. #7
    Membre émérite
    Homme Profil pro
    Inscrit en
    Décembre 2007
    Messages
    758
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France

    Informations professionnelles :
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Décembre 2007
    Messages : 758
    Par défaut
    dans les 6 fichiers tu as des informations du type:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    id1,name1
    id2,name2
    ...
    idn,namen
    et tu appliques le même traitement ?

    si oui, tu peux faire:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    filenames = ['fichier1.csv','fichier2.csv',...,'fichiern.csv']
    fichiers = []
    for _file in filenames:
       fichiers.append(open(_file,'r'))
    for _fichier in fichiers:
      for line in _fichier:
         #traitement
    ou plus concis (mais un peu plus dur à comprendre )

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    import itertools
    fichiers = [ open(_file,'r') for _file in ['fichier1.csv','fichier2.csv',...,'fichiern.csv'] ]
    for line in itertools.chain(*fichiers):
        #traitement
    à ma connaissance, on ne peut pas en python pur connaitre le nombre de lignes du fichier sans l'ouvrir.

  8. #8
    Rédacteur
    Avatar de Zavonen
    Profil pro
    Inscrit en
    Novembre 2006
    Messages
    1 772
    Détails du profil
    Informations personnelles :
    Âge : 77
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 1 772
    Par défaut
    Y a-t-il un moyen de connaître la longueur d'un fichier sans le charger ?
    Il faut quand même l'ouvrir:
    Code python : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    fp=open("blabla.txt","r")
    oldpos=fp.tell() #récupérer position du pointeur
    fp.seek(0,2)  #aller en fin de fichier
    length=fp.tell() #donner la position de la tête de lecture
    fp.seek(oldpos) #replacer le pointeur à la position intiale
    print length #afficher le résultat
    Ce qu'on trouve est plus important que ce qu'on cherche.
    Maths de base pour les nuls (et les autres...)

  9. #9
    Membre émérite
    Homme Profil pro
    Inscrit en
    Décembre 2007
    Messages
    758
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France

    Informations professionnelles :
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Décembre 2007
    Messages : 758
    Par défaut
    j'avais compris dans le message de yoshik une taille exprimées en lignes (comme le résultat de la commande wc -l sur Unix).

    pour la taille en octet, il y a un moyen pour connaitre cette taille via stat:

    http://docs.python.org/library/os.html#os.stat

    il y est dit que c'est compatible windows et unix

  10. #10
    Rédacteur
    Avatar de Zavonen
    Profil pro
    Inscrit en
    Novembre 2006
    Messages
    1 772
    Détails du profil
    Informations personnelles :
    Âge : 77
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 1 772
    Par défaut
    Code python : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    import os
    statinfo=os.stat("blabla.txt")
    print statinfo.st_size
    sous linux ça marche (donne le même résultat que précédemment)
    Ce qu'on trouve est plus important que ce qu'on cherche.
    Maths de base pour les nuls (et les autres...)

  11. #11
    Membre confirmé
    Profil pro
    Inscrit en
    Septembre 2008
    Messages
    105
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2008
    Messages : 105
    Par défaut
    Bonsoir,

    Merci...
    Je me suis mal exprimé. Par taille, je voulais dire effectivement "nombre d'enregistrements".
    Mais je vais ouvrir une discussion propre sinon anass_59 ne va plus "y retrouver ses petits".

    A tout de suite
    @+

  12. #12
    Membre émérite
    Homme Profil pro
    heu...
    Inscrit en
    Octobre 2007
    Messages
    648
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : heu...

    Informations forums :
    Inscription : Octobre 2007
    Messages : 648
    Par défaut
    Est-ce que c'est via un script que tu défini ton fichier csv ? si oui, alors peut être qu'une solution base de donnée serait plus simple (une base de donnée simple, bsddb en tête).

    Avec le module bsddb, tu peux créer des fichier de base de donnée (bsddb évidement), ces fichiers s'utilisent comme un dictionnaire. dans ce module il existe trois type de bdd (base de donnée) : le type hash, la plus rapide des trois, mais aucun classment, comme un dictionnaire quoi, le type rn, celui-ci conserve l'ordre dans lequel les données ont étés ajoutées, et enfin le type bt (binary tree), qui lui possède un ordre alphabétique, chaque nouvelle donnée est inserée au bon endroit. Ces trois types s'utilisent de la même façon, mais le type hash est celui qui offre le moins de fonctionnalités, et le type bt, le plus.

    un exemple (directement tiré de python.org):
    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
    >>> import bsddb
    >>> db = bsddb.btopen('./puissances.db')
    >>> d={}
    >>> for i in range(10):
    	d[str(i)]=str(i**2)
    >>> for k in d.keys():
    	print k
    	db[k]=str(d[k])
     
     
    1     #c'est juste pour montrer l'ordre dans lequel les données sont ajoutées :
    0     #cad aucun
    3
    2
    5
    4
    7
    6
    9
    8
    >>> db.keys()
    ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9']
    >>> db['8']
    '64'
    >>> db.set_location('0')
    ('0', '0')
    >>> db.next()
    ('1', '1')
    >>> db.next()
    ('2', '4')
    >>> db.previous()
    ('1', '1')
    >>> db.last()
    ('9', '81')
    >>> db.first()
    ('0', '0')
    >>> db.next()
    ('1', '1')
    >>> '11' in db
    False
    >>> '1' in db
    True
    >>> db.isOpen()
    True
    >>> db.items()
    [('0', '0'), ('1', '1'), ('2', '4'), ('3', '9'), ('4', '16'), ('5', '25'), ('6', '36'), ('7', '49'), ('8', '64'), ('9', '81')]
    >>> db.close()#ne pas oublier de fermer, une fois qu'on à fini
    Simple, et rapide.

    doc : http://docs.python.org/library/bsddb.html#module-bsddb

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

    S'il s'agit seulement d'afficher le contenu du fichier csv, voilà comment on peut faire:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    nfc = r"C:\Python25\Pydev\test\testcsv.txt"
     
    L = []
    f = open(nfc,"r")
    for ligne in f:
        L.append(ligne.rstrip("\r\n").split(";"))
    f.close()
    L.pop(0)
     
    for id, nom in L:
        print id, nom
    le 'r' devant le chemin du fichier nfc permet de conserver les '\' tels quels
    la méthode rstrip() retire les caractères de fin de ligne
    la méthode split() découpe la chaine selon le séparateur ';'
    la méthode pop() retire la 1ère ligne

    Tyrtamos

  14. #14
    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
    Si « Chaque ligne contient un id de l'élève ainsi que son nom» signifie que sur chaque ligne l’id de l’élève est suivi de son nom,

    et si «afficher le nom de l'élève pour chaque id» signifie qu’il faut afficher l’id suivi du nom de l’élève,

    je ferais

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    f = open('fichier.csv')
    f.readline()
    for ln in f:
        print ln[0:-1].replace(';'," ")
    f.close()
    L’exécution de f.readline() sans affectation fait avancer le pointeur du fichier à la deuxième ligne.



    Pour récupérer en variables l’id et le nom pour usage supplémentaire, on peut faire

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    f = open('fichier.csv')
    f.readline()
    for ln in f:
        u,_,v = ln[0:-1].partition(';')
        print u,v
    f.close()


    Si le fichier contient en fait des couples id-nom qui se répètent sur diverses lignes et qu’il s’agit de n’afficher chaque couple qu’une fois, alors il faut faire un traitement plus développé.





    À mon avis , rstrip(’\n’) suffit car, à moins d’indiquer à Python qu’on veut obtenir une ligne avec la terminaison précise qu’elle a dans le fichier, il squeeze n’importe quelle fin de ligne pour en faire une fin de ligne ’\n’ .

    Dans ces conditions, on peut éçrire ln[:-1] au lieu de ln.rstrip(’\n’).
    Je pense que l’utilisation d’une notation indicielle plutôt que d’une méthode de chaîne est plus rapide. Si le fichier est court, évidemment , on s’en fiche.

  15. #15
    Membre averti
    Profil pro
    Étudiant
    Inscrit en
    Mai 2009
    Messages
    50
    Détails du profil
    Informations personnelles :
    Âge : 35
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Mai 2009
    Messages : 50
    Par défaut
    Slt tout le monde... Et oui c'est moi celui qui a posé cette requette, et depuis ce weekend, je suis la discussion qui m'a beaucoup apporté pour la solution du problème que je cherche à résoudre. J'ai finalement adapté la dernière formule qui me parait la plus facile et la plus courte d'entre toutes. Après quelques modifications biensur, j'arrive presque à afficher le résultat voulu. Mais à une exception pret....

    Pour revenir à l'exemple cité à mainte reprise, si par exemple, je possède un fichier csv de trois colonnes par ligne, les deux premières contiennent des id et dates d'inscription, et la troisième le nom, qui parfois peut contenir des chiffre aussi.
    J'essaie de parser ces données et de n'afficher que le nom de l'élève correspondant à chaque ID, sans prendre en compte la date, et à la fin stocké ce nom dans une variable comme par exemple nom_eleve....

    Merci à tous

  16. #16
    Membre expérimenté
    Profil pro
    Inscrit en
    Avril 2008
    Messages
    159
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2008
    Messages : 159
    Par défaut
    Citation Envoyé par anass_59 Voir le message
    Slt tout le monde... Et oui c'est moi celui qui a posé cette requette, et depuis ce weekend, je suis la discussion qui m'a beaucoup apporté pour la solution du problème que je cherche à résoudre. J'ai finalement adapté la dernière formule qui me parait la plus facile et la plus courte d'entre toutes. Après quelques modifications biensur, j'arrive presque à afficher le résultat voulu. Mais à une exception pret....

    Pour revenir à l'exemple cité à mainte reprise, si par exemple, je possède un fichier csv de trois colonnes par ligne, les deux premières contiennent des id et dates d'inscription, et la troisième le nom, qui parfois peut contenir des chiffre aussi.
    J'essaie de parser ces données et de n'afficher que le nom de l'élève correspondant à chaque ID, sans prendre en compte la date, et à la fin stocké ce nom dans une variable comme par exemple nom_eleve....

    Merci à tous
    Tu as une ligne d'en-têtes dans ton fichier csv, avec le nom de chaque colonne ?

    Dans ce genre de cas j'utilise le module csv avec le reader csv.DictReader pour lire le fichier.
    Avec ça, je me retrouve avec une liste de dictionnaires, chaque dictionnaire correspond à une ligne du fichier, les clés étant les nom de colonnes.

    Ensuite, ne sortir que les lignes correspondant à tel ou tel champ ne sont qu'un jeu d'enfant.

Discussions similaires

  1. traitement d'un fichier txt par un srcipt shell
    Par GHISLINO dans le forum Linux
    Réponses: 12
    Dernier message: 07/11/2011, 13h05
  2. Réponses: 93
    Dernier message: 15/04/2009, 15h34
  3. traitement d'un fichier txt
    Par arezki76 dans le forum Shell et commandes GNU
    Réponses: 7
    Dernier message: 22/06/2007, 14h36
  4. Réponses: 9
    Dernier message: 03/01/2007, 17h06

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