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 :

Problème itération d'un fichier plat avec variables temporaires en fonction d'une clé


Sujet :

Python

  1. #1
    Membre du Club
    Profil pro
    Inscrit en
    Mai 2010
    Messages
    46
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2010
    Messages : 46
    Points : 47
    Points
    47
    Par défaut Problème itération d'un fichier plat avec variables temporaires en fonction d'une clé
    Bonjour,

    Je suis sous Python 2.5 et j'ai un problème algorithmique de base voici mon besoin:

    Ma finalité est de produire un fichier XML bien encapsulé à partir d'un fichier plat .txt

    Dans mon fichier source, pour chaque ligne j'ai une clé (avec séparateur "_"):

    Exemple:
    07._LEZ_27.7.f_XEU_FRA_LEZ
    07._LEZ_27.7.g_XEU_FRA_COD
    07._LEZ_27.7.g_XEU_FRA_HET
    2A-14_JAX_27.8.b_XEU_ESP_JAX
    7X7A-C_WHG_27.7.f_XEU_FRA_WHG

    Voici le résultat attendu:
    Un tri par => index(0) & index(1) / index(2) & index(3) & index(4) / index(5)

    C'est à dire en sortie:
    07._LEZ
    27.7.f_XEU_FRA
    LEZ
    27.7.g_XEU_FRA
    COD
    HET
    2A-14
    JAX_27.8.b_XEU_ESP
    JAX
    7X7A-C
    WHG_27.7.f_XEU_FRA
    WHG

    Avez-vous des idées de pseudo code avec des variables temporaires pour me permettre de gérer ceci?
    Merci beaucoup pour votre aide..

  2. #2
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 283
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 283
    Points : 36 770
    Points
    36 770
    Par défaut
    Citation Envoyé par davtypo3 Voir le message
    Dans mon fichier source, pour chaque ligne j'ai une clé (avec séparateur "_"):
    Ca commence par:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    >>> s = '07._LEZ_27.7.f_XEU_FRA_LEZ'
    >>> z = s.split('_')
    >>> z
    ['07.', 'LEZ', '27.7.f', 'XEU', 'FRA', 'LEZ']
    >>>
    Citation Envoyé par davtypo3 Voir le message
    Avez-vous des idées de pseudo code avec des variables temporaires pour me permettre de gérer ceci?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    >>> '_'.join(z[:2])
    '07._LEZ'
    >>> '_'.join(z[2:5])
    '27.7.f_XEU_FRA'
    >>> z[-1]
    'LEZ'
    Maintenant, vous avez une première fonction:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    >>> def zsplit(line):
    ...     z = line.split('_')
    ...     return ''.join(z[:2]), ''.join(z[2:5]),  z[-1]
    ...
    >>> zsplit(s)
    ('07.LEZ', '27.7.fXEUFRA', 'LEZ')
    Le reste n'est pas plus complique, si?
    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  3. #3
    Membre du Club
    Profil pro
    Inscrit en
    Mai 2010
    Messages
    46
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2010
    Messages : 46
    Points : 47
    Points
    47
    Par défaut
    Merci de votre aide,

    En fait je n'ai pas de problème pour la récupération des valeurs, c'est plutôt l'algo qui m'en pose, pour générer la sortie le plus simplement possible...
    Une idée?

  4. #4
    Membre éprouvé

    Homme Profil pro
    Ingénieur
    Inscrit en
    Août 2010
    Messages
    654
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Août 2010
    Messages : 654
    Points : 1 150
    Points
    1 150
    Par défaut
    Salut,

    A vu de nez, je tenterais une approche à l'aide de dictionnaires.

    J

  5. #5
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 283
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 283
    Points : 36 770
    Points
    36 770
    Par défaut
    Salut,
    Soit une liste bien rangée (L[i] < L[i+1], qqs i)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    >>> L = [ "AAA", "AAB", "ABA", "BAA" ]
    Pour faire les affichages décales, on fabrique une petite fonction:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    >>> def print_at(s, level):
    ...     blanks = ' ' * (level * 2)
    ...     print (blanks, s)
    ...
    Puis on traite le premier élément (qui devient le dernier):
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    >>> last = L[0]
    >>> for ix, s in enumerate(last):
    ...     print_at(s, ix)
    ...
     A
       A
         A
    Et on s'occupe du reste:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    >>> for t in L[1:]:
    ...     for ix, s in enumerate(t):
    ...         if s != last[ix]:
    ...             print_at(s, ix)
    ...     last = t
    ...
         B
       B
         A
     B
       A
    - W
    PS: Python est polymorphique "AAA" ou un tuple a 3 éléments c'est "pareil" (ici).
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  6. #6
    Membre éprouvé

    Homme Profil pro
    Ingénieur
    Inscrit en
    Août 2010
    Messages
    654
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Août 2010
    Messages : 654
    Points : 1 150
    Points
    1 150
    Par défaut
    Salut,

    En reprenant un peu la notation de Wiztricks, mais en partant sur un dictionnaire, on peut faire ceci:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    l = ['07._LEZ_27.7.f_XEU_FRA_LEZ',
         '07._LEZ_27.7.g_XEU_FRA_COD',
         '07._LEZ_27.7.g_XEU_FRA_HET',
         '2A-14_JAX_27.8.b_XEU_ESP_JAX',
         '7X7A-C_WHG_27.7.f_XEU_FRA_WHG']
     
    dico = {}    
    for s in l:
        z = s.split('_')
        dico.setdefault('_'.join(z[0:2]),{}).setdefault('_'.join(z[2:5]),[]).append(z[5:])
     
    print dico
    L'intérêt du dictionnaire ici est l'unicité des clés, ce qui permet de faire ceci:

    07._LEZ
    27.7.f_XEU_FRA
    LEZ
    27.7.g_XEU_FRA
    COD
    HET

    Les deux chaines en gras sont des valeurs différentes, mais ayant la même "clé" 27.7.g_XEU_FRA. En reprenant les idées de Wiztricks, tu ne devrait pas avoir de problème pour assembler ton code.

    J

    PS: Oui, la construction de mon dico est dégeulasse, mais j'assume!

  7. #7
    Membre du Club
    Profil pro
    Inscrit en
    Mai 2010
    Messages
    46
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2010
    Messages : 46
    Points : 47
    Points
    47
    Par défaut
    Déjà merci,
    juste pour préciser, j'ai 4 jours d'XP en Python...
    Donc la synthaxe de wiztricks (qui est problablement la plus pythonique), j'ai un peu de mal à la comprendre, mais je vais regarder quand même, et essayer d'intégrer ça logique, voici ce que j'ai produit hier:

    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
     
                # Open source file
                oFileHandle = open(self.sInputFile, 'rb');
                oReader = csv.reader(oFileHandle, delimiter = '\t'); # Reader pointer
     
                # Skip header lines if needed
                if self.iStartRow >=0:
                    for i in xrange(self.iStartRow):
                        i += 1; # Do nothing, but use the variable, because we want to avoid "Warning"
                        oReader.next(); # Skip line N time regarding self.iStartRow
     
                # Set dictionary
                aDictionary = {};
                i = 0;
                for row in oReader:
                    i += 1; # Hack, add [i] increment because sorted() delete duplicate key when sorting
                    aDictionary[row[19] + '_' + str(i)] = row; # key, value[row]
     
                # Start iterate sorted dictionary
                sTempSpecifiedRegional = '';
                sTempSpecifiedReportedArea = '';
     
                for key in sorted(aDictionary.iterkeys()):
                    aRow = aDictionary[key]; # Dictionary row
                        print str(aRow[19]);   
                        sPattern = aRow[19].split('_');
     
                        sSpecifiedRegional = sPattern[0] + sPattern[1];
                        sSpecifiedReportedArea = sPattern[2] + sPattern[3] + sPattern[4];                                      
                        sQuantifiesReportedCatch = sPattern[5];
     
                        if sSpecifiedRegional <> sTempSpecifiedRegional:
                            print 'step1 : ', sSpecifiedRegional;
     
                            if sSpecifiedReportedArea <> sTempSpecifiedReportedArea:
                                print '\tstep2 : ' + sSpecifiedReportedArea;
                                print '\t\tstep3 : ' + sQuantifiesReportedCatch;
                                sTempSpecifiedReportedArea = sSpecifiedReportedArea;
                            sTempSpecifiedRegional = sSpecifiedRegional;
                        else:
                            print '\t\tstep4 : ' + sQuantifiesReportedCatch;


    Voici l'ouput, cela semble me convenir pour le moment, je vais bien tester dans tous les sens...

    07._LEZ_27.7.f_XEU_FRA_COD
    step1 : 07.LEZ
    step2 : 27.7.fXEUFRA
    step3 : COD
    07._LEZ_27.7.f_XEU_FRA_LEZ
    step4 : LEZ
    2A-14_JAX_27.8.b_XEU_ESP_JAX
    step1 : 2A-14JAX
    step2 : 27.8.bXEUESP
    step3 : JAX
    7X7A-C_WHG_27.7.f_XEU_FRA_WHG
    step1 : 7X7A-CWHG
    step2 : 27.7.fXEUFRA
    step3 : WHG

  8. #8
    Membre du Club
    Profil pro
    Inscrit en
    Mai 2010
    Messages
    46
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2010
    Messages : 46
    Points : 47
    Points
    47
    Par défaut
    Ok, finalement ça fonctionne, mais avec mon code, c'est pas du tout optimisé (j'ai + de 60 lignes), pouvez-vous jeter un oeil entre la ligne 103 et 164 (ne pas tenir compte de la création des nodes XML), c'est la logique de récupération des données dans des variables temporaires qui m’intéresse...

    Merci beaucoup,
    Fichiers attachés Fichiers attachés

  9. #9
    Expert éminent sénior
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 283
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 283
    Points : 36 770
    Points
    36 770
    Par défaut
    Salut,

    Si votre code fonctionne tant mieux pour vous.

    247 lignes de scripts reparties en 4 fonctions: main, __init__, build_regional_report, write_xml_report.
    build_regional_report fait 140 lignes a elle seule: normal vu le nombre d'actions qu'elle effectue.
    Tel que vous avez organise votre code, vous auriez très bien pu vous passer de créer ces quatre fonctions.
    Après tout, aucune n’étant appelée plus d'une fois, techniquement elles ne servent a rien.

    Vous avez des outils de vérification de qualité du code qui s'amusent a regarder le nombre d'instructions par fonctions: des que ça dépasse 10, vous devez vous poser des questions.

    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

Discussions similaires

  1. Problème itération avec variables temporaires en fonction d'une clé
    Par davtypo3 dans le forum Algorithmes et structures de données
    Réponses: 0
    Dernier message: 12/02/2014, 15h42
  2. Réponses: 2
    Dernier message: 27/12/2010, 13h46
  3. Réponses: 6
    Dernier message: 12/04/2007, 14h22
  4. [DOM4J] Problème de lecture de fichier xml avec dom4j
    Par santana2006 dans le forum Format d'échange (XML, JSON...)
    Réponses: 3
    Dernier message: 05/04/2006, 16h52
  5. problème pour parser un fichier xml avec XML::Simple
    Par black_code dans le forum Modules
    Réponses: 3
    Dernier message: 30/01/2006, 19h32

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