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 :

Utilisation d'un object file


Sujet :

Python

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Août 2007
    Messages
    42
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2007
    Messages : 42
    Par défaut Utilisation d'un object file
    Bonjour,

    J'ai un soucis et j'aimerai savoir si il existe une solution rapide.

    Fichier utilisé :

    tarataratartaratar
    tar tar atar tarat
    etc...
    Static Molecule :: /home/teteteraraetar/raertaer.ligand.pdb
    Mobile Molecule :: /home/teteteraraetar/raertaer.ligand.pdb

    etc... beaucoup beaucoup de ligne ....


    Je dois scanner les adresses en face de Static et Mobile molécule et vérifier qu'elles ne dépassent pas 60 caractères le cas échéant je changerai celle ci.


    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
     
            file = open("monfichier","r")
            data = file.read()
            #file.close()
     
            address_rec = re.compile("Static molecule (.*?)\n").findall(data)[0].split("::")[1].strip()
            address_lig = re.compile("Mobile molecule (.*?)\n").findall(data)[0].split("::")[1].strip()
     
     
            if 1:#(len(address_rec)>=60) and (len(address_lig)>=60):
                data_line = file.readlines()
                print data_line
                for i in data_line:
     
                    if re.search("^Static molecule",i):
                        print "Static molecule                    :: %s"%(nouvelle adress) # TODO ecriture fichier
                    else:
                          pass # TODO ecriture du fichier
    Le soucis c'est que je peux pas faire un second readlines sur mon objet file. Certes je pourrai l'ouvrir 2 fois mais je voulais savoir si il existe une autre solution.
    Et est ce que mon code est optimal pour ce genre d'opération.
    Merci pour votre aide,

    Mister

  2. #2
    Membre émérite

    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
    Par défaut
    Si tu as un gros fichier à manipuler, il vaut mieux éviter d'utiliser read()

    Tu peux itérer sur les lignes directement
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    for line in file:
        #traitement
    (N.B. file est le nom d'une classe Python)

    Mis à part ça, pourquoi utiliser findall si c'est pour ne garder que le premier résultat ?

  3. #3
    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
    Chouette, un truc bien complexe et pas trop compliqué.

    Le problème, c'est que tu n'expliques pas suffisamment ce que tu veux faire: «je changerai celle ci», c'est un peu court.
    Le changement envisagé ferait-il changer la longueur d'une ligne modifiée ? Si ce n'est pas le cas, je te suggère modestement de consulter le post suivant que j'ai commis, une solution avec le mode 'r+' étant envisageable:

    http://www.developpez.net/forums/d65...chier-mode-rp/

    Sinon, il va falloir recourir à la récriture dans un nouveau fichier.

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

    Aussi: à quel caractère de
    'Static Molecule :: /home/teteteraraetar/raertaer.ligand.pdb'
    commencent les 60 caractères impératifs ?


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


    «Le soucis c'est que je peux pas faire un second readlines sur mon objet file.»
    Pourquoi veux-tu faire un second readlines() ?

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

    J'ai regardé ton code, rapidement, mais je me demande si les lignes
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
            address_rec = re.compile("Static molecule (.*?)\n").findall(data)[0].split("::")[1].strip()
            address_lig = re.compile("Mobile molecule (.*?)\n").findall(data)[0].split("::")[1].strip()
    ne sont pas des marteaux-piqueurs pour casser une noisette. Excuse moi, je n'ai pas encore regardé à fond et donc pas encore compris ce que tu veux faire avec ces deux lignes.

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

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    if re.search("^Static molecule",i):
    sera avantageusement remplacé par
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    if i[0:15]=='Static molecule':
    plus naturel et plus rapide.


    All that, IMHOAWW.

  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
    Quelques remarques à propos des expressions régulières que tu emploies,
    sous réserve que je ne fasse pas d'erreur dans ce domaine assez complexe:

    Pour comprendre ces regex, il vaut mieux prendre les choses progressivement:

    Avec
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    ch = 'cinq SAUcissons secs\nkjhSAUf-conduit 765\nwindows\n9879769\
    764SAUmon 23 euros\nkjjgkgssff\nSAUpoudrage'
    1/
    trouve toutes les portions de ch composées de:
    3 premiers caractères 'SAU' + obligatoirement tous(éventuellement zéro s'il n'y en a pas) les caractères jusqu'à un caractère '\n' (car le point '.' d'une regex ne matche pas '\n')
    Résultat:
    ['SAUcissons secs', 'SAUf-conduit 765', 'SAUmon 23 euros', 'SAUpoudrage']

    2/
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    re.findall('SAU.*?',ch)
    trouve toutes les portions de ch composées de:
    3 premiers caractères 'SAU' + ÉVENTUELLEMENT tous(éventuellement zéro) les caractères jusqu'à un caractère '\n'
    Comme .*? signifie Éventuellement, la regex ne se fatigue pas: dès qu'elle a trouvé 3 caractères 'SAU', elle déçlare qu'ils matchent et elle s'arrête (jusqu'à trouver la portion suivante, parce qu'il s'agit de findall).
    Donc cette fois résultat:
    ['SAU', 'SAU', 'SAU', 'SAU']


    3/
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    re.findall('SAU.*?\n',ch)
    trouve les mêmes portions que précédemment mais qui vont obligatoirement jusqu'à '\n'. La présence de '\n' dans la regex force le caractère facultatif de '.*?' à tomber et la regex entière à aller jusqu'à la fin de la ligne. Le line break '\n' est pris dans le match; résultat:
    ['SAUcissons secs\n', 'SAUf-conduit 765\n', 'SAUmon 23 euros\n']
    C'est comme en 1, avec '\n' en plus.





    Si on ajoute des parenthèses, on crée un groupe.
    C'est à dire que findall() ne va plus donner chaque match complet (ce que j'appelle une portion matchante de la chaine examinée) mais pour chaque match (cad chaque portion matchante) les différents morceaux de la portion matchante qui matchent avec les différents groupes qui sont définis dans la regex.
    - La regex matche avec la portion matchante.
    - Chaque morceau de la portion matche (ou ne matche pas; mais il faut un minimum de portions qui matchent avec des groupes définis dans la regex, quand il y a plusieurs groupes) avec un groupe de la regex.


    Ici, comme il n'y a qu'un groupe défini dans la regex, findall() donne le seul morceau de la portion matchante qui matche avec le groupe de la regex.

    C'est abscons, mais ce n'est pas moi qui ai inventé tout ça.

    Ainsi toujours avec
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    ch = 'cinq SAUcissons secs\nkjhSAUf-conduit 765\nwindows\n9879769\
    764SAUmon 23 euros\nkjjgkgssff\nSAUpoudrage'
    4/
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    print re.findall('SAU(.*)',ch)
    donne pour résultat:
    ['cissons secs', 'f-conduit 765', 'mon 23 euros', 'poudrage']
    On vérifie bien que 'SAU' n'est pas présent dans ce que donne findall(), puisque 'SAU' se trouve avant le groupe (.*) dans la regex.

    5/Si on rend le groupe facultatif (.*?), la regex fait comme plus haut, elle s'arrête de chercher dès qu'elle a matché une succession 'SAU' et le groupe (.*?) n'est mis en matching avec rien du tout, d'où le résultat:
    ['', '', '', '']

    Enfin, dans
    6/
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    re.findall('SAU(.*?)\n',ch)
    la présence de '\n' oblige la regex à matcher jusqu'au bout des lignes, mais comme findall() n'indique que le morceau de chaque match qui matche avec le groupe défini (.*?), on se retrouve avec le même résultat qu'un peu plus haut parce que les morceaux ne contiennent pas '\n', même si ce caractère est indispensable pour forcer le groupe à matcher avec un morceau situé après chaque 'SAU'.
    Résultat:
    ['cissons secs', 'f-conduit 765', 'mon 23 euros']

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

    Passons maintenant aux regex que tu écris.
    Une partie donne l'impression que tu sais ce que tu veux: l'utilisation d'un groupe pourrait te donner directement la sous-chaine voulue.
    Mais autre chose en fait douter: un split() sur une chaine contenant le séparateur une seule fois, en tête de chaine..... ....

    On voit qu'avec re.compile("Static Molecule (.*?)\n") , la fonction findall() va donner la liste des morceaux dont chacun matche dans chaque ligne avec (.*?), c'est à dire
    [':: /home/teteteraraetar/raertaer.ligand.pdb',
    ':: /home/titaorarweyur/raeaer.lignood.pdb',
    etc ]


    En mettant [0] après findall(data) , le résultat est que cela désigne le premier morceau matchant de la liste, soit
    ':: /home/teteteraraetar/raertaer.ligand.pdb'.
    Tout ça pour ça........


    re.compile("Static Molecule (.*?)\n").findall(data)[0].split("::") va séparer "" de " /home/teteteraraetar/raertaer.ligand.pdb"
    et re.compile("Static Molecule (.*?)\n").findall(data)[0].split("::")[1].strip()
    va enlever le malheureux petit blanc en tête de
    " /home/teteteraraetar/raertaer.ligand.pdb"

    Ça me semble être beaucoup de travail pour pas grand chose et ce ne doit même pas être ce que tu cherches à obtenir.

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

    Tu pourrais y arriver plus directement avec
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    file = open("monfichier","r")
    data = file.read()
    address_rec = re.compile("Static molecule :: (.*?)\n").findall(data)
    qui donne
    ['/home/teteteraraetar/raertaer.ligand.pdb',
    '/home/teuwytqwar/rarrrrrer.ligand.pdb',
    etc]


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

    Mais j'estime que c'est employer une tronçonneuse pour couper la bûche de Noël et que le code suivant est suffisant:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    file = open("monfichier","r")
    fo ln in file:
        if ln[0:15]=='Static molecule':
            finln = ln.partition('molecule :: ')[2]
    pour disposer de façon réitérée dans finln de '/home/teteteraraetar/raertaer.ligand.pdb' qui peut être traitée tout de suite,
    sans avoir à créer un éventuellement gros fichier dat = file.read() et une éventuellement grosse liste address_rec, comme l'a indiqué oiffrig.

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

    Bon , après avoir trouvé une analyse des lignes plus satisfaisante que des regular expressions, il restera à comprendre ce que tu veux faire comme modification de ligne.

  5. #5
    Membre averti
    Profil pro
    Inscrit en
    Août 2007
    Messages
    42
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2007
    Messages : 42
    Par défaut
    Merci beaucoup pour vos réponses !

    C'est vrai qu'en me relisant je n'ai pas étais très clair excuser moi !

    En faite j'ai un fichier qui peut etre très très gros. Je veux scanner le début du fichier pour récupérer les adresses en face de Static molecule et Mobile molecule (Static Molecule :: /adress que je veux récuperer/). Si ces adresses dépassent 60 characteres je veux pouvoir mettre à la place une nouvelle adresse.
    Donc si + de 60 caracteres je modifie juste les deux adresses au début du fichier, le reste est inchangé.

    J'ai utilisé re.compile car je pensais que c'était beaucoup plus rapide que re.search (pas de boucle pour compile).
    Et je pensais également que read() était plus rapide que readlines() ce qui explique que j'ai utilisé d'abord read pour trouver les adresses et les tester et ensuite readlines() pour aller les modifier.

    G

  6. #6
    Membre averti
    Profil pro
    Inscrit en
    Août 2007
    Messages
    42
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2007
    Messages : 42
    Par défaut
    Merci beaucoup pour les explications exhaustives sur les regex je comprends enfin comment ça marche car j'avoue que en faite j'utilise les regex un peu au hasard pour trouver ce que je cherche.

    Maintenant ce que je cherche à faire c'est à changer les adresses scannées aprés molécule (il n'y a que 2 adresses celle de static molecule et celle de mobile molecule).

    Merco encore pour votre aide !

    G

  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
    «Si ces adresses dépassent 60 caractères je veux pouvoir mettre à la place une nouvelle adresse.»

    Quelle est la longueur de chacune des adresses remplaçantes ?
    Inférieure ou égale à 60, je suppose.

    Est-ce que chaque ligne modifiée peut garder la même longueur, quitte à ce que la fin soit remplie de blancs, ou est-ce que tu veux que la fin d'une adresse soit aussi la fin de la ligne ?

  8. #8
    Membre averti
    Profil pro
    Inscrit en
    Août 2007
    Messages
    42
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2007
    Messages : 42
    Par défaut
    Oui inférieur à 60 characters, je cree un temp avec la lib tempfile en faite.
    Une fin de ligne aprés l'adresse est parfaite.

    G

    PS : partition ne fonctionne qu'à partir de la version 2.5 je tourne en 2.4 sur mes clusters et j'ai pas trop le courage de tout mettre à jour (et peur de perte de compatibilité avec mes autres scripts), il existe une alternative à partition ?

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

Discussions similaires

  1. Alerte en utilisant la balise object
    Par gloglo dans le forum Balisage (X)HTML et validation W3C
    Réponses: 0
    Dernier message: 09/06/2008, 09h39
  2. Réponses: 1
    Dernier message: 28/03/2007, 12h01
  3. object file dans un vecteur
    Par chti_juanito dans le forum API standards et tierces
    Réponses: 4
    Dernier message: 09/05/2006, 09h42
  4. 8i sur Linux : Erreur loadin shared object file
    Par NGONGO ETABA dans le forum Oracle
    Réponses: 2
    Dernier message: 24/03/2006, 11h40
  5. Réponses: 6
    Dernier message: 15/01/2005, 23h34

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