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 :

Adapter le nombre de variables en fonction du nombre d'inputs


Sujet :

Python

  1. #1
    Membre confirmé
    Inscrit en
    Mars 2012
    Messages
    73
    Détails du profil
    Informations forums :
    Inscription : Mars 2012
    Messages : 73
    Par défaut Adapter le nombre de variables en fonction du nombre d'inputs
    Bonjour,

    je viens (une fois encore) exposer une question que je n'ai pas encore résolu. Je suis face à un cas (peu être triviale ?) que je n'avais pas encore rencontré jusque là.

    J'ai fait un programme qui traite des fichiers qui lui sont passés en entrée. Je stocke chacun d'eux dans une liste, puis j'effectue un premier traitement, et enfin dans un dictionnaire, pareil j'effectue un second traitement. Tout fonctionne parfaitement, seulement mon programme est figé, c'est à dire que je considère toujours le même nombre de fichiers en entrée, et je définis donc à l'avance mes listes / dicos que j'utiliserai par la suite.

    Ma question est la suivante, comment faire pour anticiper le nombre d'inputs et créer le bon nombre de variables correspondant au nombre de fichiers en entrée ?

    En considérant que mes fichiers d'entrée soient contenus dans une liste, j'avais pensé à ça pour créer autant de liste que j'ai de fichiers:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    for i in range(len(fichiers)):
            i=[]
    et donc créer une liste portant le nom de l'incrémentation, mais je doute que se soit éfficace.

    Sinon j'avais pensé à quelque chose de lourd, mais qui je pense peu marcher, c'est à dire créer une fonction dans laquelle je définis préalablement les variables dont j'aurai besoin( liste1[],liste2[],dico1{},dico2{}...) pour chaque cas de figures. Dans ce cas là j'aurai juste à appeler la fonction qui correspond au bon nombre de fichiers passés en entrée.

    Qu'en pensez vous ?

  2. #2
    Membre confirmé
    Inscrit en
    Mars 2012
    Messages
    73
    Détails du profil
    Informations forums :
    Inscription : Mars 2012
    Messages : 73
    Par défaut
    Sinon j'avais pensé à quelque chose de lourd, mais qui je pense peu marcher, c'est à dire créer une fonction dans laquelle je définis préalablement les variables dont j'aurai besoin( liste1[],liste2[],dico1{},dico2{}...) pour chaque cas de figures. Dans ce cas là j'aurai juste à appeler la fonction qui correspond au bon nombre de fichiers passés en entrée.
    Bon malgré le fait que je multiplie la taille de mon code cette méthode marche plutôt bien, je considère le problème comme résolu mais je suis ouvert à toutes critiques / suggestions

  3. #3
    Membre Expert

    Homme Profil pro
    Diverses et multiples
    Inscrit en
    Mai 2008
    Messages
    662
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Diverses et multiples

    Informations forums :
    Inscription : Mai 2008
    Messages : 662
    Par défaut
    Citation Envoyé par michel42 Voir le message
    Bon malgré le fait que je multiplie la taille de mon code cette méthode marche plutôt bien, je considère le problème comme résolu mais je suis ouvert à toutes critiques / suggestions
    Houlàlà, oui, ça c’est du lourd*!

    Si l’on part du principe que tu as une liste contenant un nombre variable de fichiers, le plus simple est de créer un liste "globale", du même nombre d’éléments que tu as de fichiers, chaque éléments contenants les variables dont tu as besoin. Par exemple*:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    files = ["foo.bar", "crazy/fish.april"]
    data = []  # la liste qui contiendra tout.
    nbr_files = len(files)  # la fonction len() renvoie le nombre d’éléments d’une liste, d’un dico, …
    for i in range(nbr_files):
        data.append(([] , {}))
    # data contient maintenant un tuple (liste, dico) pour chaque fichier
    # Pour accéder à la liste du deuxième fichier*: data[1][0]
    Ça, c’était la version “longue”, pour le plaisir voici la version condensée*:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    files = ["foo.bar", "crazy/fish.april"]
    data = [([], {}) for i in range(len(files))]
    Note*: si les fichiers ne sont pas liés entre eux (c-à-d si le traitement de l’un ne dépend pas de celui d’un autre), il est encore plus simple de boucler directement sur la liste de fichiers, en utilisant des variables temporaires au sein de la boucle for…

  4. #4
    Membre confirmé
    Inscrit en
    Mars 2012
    Messages
    73
    Détails du profil
    Informations forums :
    Inscription : Mars 2012
    Messages : 73
    Par défaut
    Merci mont29 pour vos explications je vais appliquer tout ça

  5. #5
    Membre confirmé
    Inscrit en
    Mars 2012
    Messages
    73
    Détails du profil
    Informations forums :
    Inscription : Mars 2012
    Messages : 73
    Par défaut
    J'ai peur de ne pas maîtriser assez le langage pour appliquer le code, j'ai réussis la partie concernant les fichiers, mais pour ce qui est des listes / dicos je bloque.

    J'ai une liste qui contient tous mes fichiers, sa longueur est donc égale aux nombres de fichiers, et j'essaie de boucler dessus pour générer autant de listes que de fichiers.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    for i in range(len(fichiers)):
    		  list=("liste" + "".join(str(i)))
    Pourriez vous m'éclairer s'il vous plaît ?

  6. #6
    Membre Expert
    Homme Profil pro
    Inscrit en
    Mars 2007
    Messages
    941
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations forums :
    Inscription : Mars 2007
    Messages : 941
    Par défaut
    Je ne comprends pas ce que tu essaies de faire avec ce bout de code, mais je ne suis pas sûr que tu as bien compris ce que mont29 te proposait. Il ne s'agit pas de créer un nombre variable de... variables (désolé), mais d'avoir une seule grosse liste qui contiendrait toutes tes autres listes et/ou dictionnaires. Donc au lieu de liste1 tu aurais data[0][0], dico1 serait data[0][1], liste2 correspondrait à data[1][0], etc.
    Dans ton traitement, tu pourras boucler sur les éléments de data au lieu d'écrire une fonction spécialisée pour chaque nombre de fichiers en entrée.

  7. #7
    Membre confirmé
    Inscrit en
    Mars 2012
    Messages
    73
    Détails du profil
    Informations forums :
    Inscription : Mars 2012
    Messages : 73
    Par défaut
    Merci pour votre explication. Oui effectivement j'ai un niveau trop faible pour maîtriser du premier coup cette technique, j'ai donc décomposé le problème et il reste une étape que je n'arrive pas à franchir.

    J'ai une liste de dicos : resultats_dico. Je parcours le 1er dico et si je retrouve la clé de se dico dans un autres dico alors j'écris cette clé ainsi que la valeur qui correspond. Seulement mon code ne fonctionne que pour une comparaison (mon dico de référence contre un autre), alors que j'aimerai que la comparaison (et donc l'écriture) se fasse pour TOUS les dicos de ma liste de dico.

    J'ai peur que mes explications soient un peu confuses

    Voici mon code

    resultats_dico[i].get(cle) retourne la valeur du dico i dont la clé correspond au 1er dico.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    for cle, valeur in resultats_dico[0].items():
    		for i,dico in enumerate(resultats_dico):
    			if cle in resultats_dico[i] :
    				c+=1
    				b=0
    				for b in range(c):
    					out=open("%s" % cle.strip('>'),"w")
    					out.write(cle +'\n'+ valeur + '\n' + cle + '\n'+  resultats_dico[i].get(cle) + '\n')

  8. #8
    Membre Expert

    Homme Profil pro
    Diverses et multiples
    Inscrit en
    Mai 2008
    Messages
    662
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Diverses et multiples

    Informations forums :
    Inscription : Mai 2008
    Messages : 662
    Par défaut
    C’est en effet un peu confus, mais si j’ai bien compris le problème, je crois qu’il y a moyen de se simplifier la vie avec quelques sets (ou ensembles, en français).

    Un set est grosso-modo une moitié de dico –*la partie “clé”. Leur intérêt est qu’ils permettent de faire des opérations d’ensemble (genre fusion, intersection, etc.) très facilement et efficacement. Par l’exemple, l’intersection de {a, b, d, e} et {a, c, e, f} renvoie {a, e} (les éléments communs aux deux ensembles).

    De plus, lorsqu’on ouvre un fichier, il ne faut pas oublier de le fermer (soit explicitement avec un file.close(), soit implicitement en utilisant with). Et mieux vaut éviter d’ouvrir et fermer des fichiers à tout bout de champ, donc plutôt stocker les données à écrire dans une liste temporaire, et tout écrire à la fin, d’un seul coup.

    Donc, je ferais comme ça:

    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
    cache = {}  # Va conserver les intersections de clés, puisque les éléments communs aux dicos 1 et 2 sont les mêmes quand on arrive au dico 2 et 1...
    files = {}  # Va contenir toutes les données à écrire, avec comme clés les différents fichiers cibles.
    for i, dico in enumerate(resultats_dico):
        # 1. On calcule les intersections avec les clés de tous les dicos suivants (les précédentes ont déjà été calculées lors des itérations précédentes et sont déjà dans le cache)
        for j, d in enumerate(resultats_dico[i + 1:]:  # Uniquement les dicos restant après celui en cours…
            cache[(i, j + i + 1)] = set(dico) & set(d)  # Et voilà, cache[(x, y)] contient les clés communes aux dicos x et y*!
        # 2. On utilise ce qu’on a déjà calculé précédemment...
        for j, d in enumerate(resultats_dico):
            if j == i:
                continue  # Ne pas traiter un dico contre lui-même*!
            if j < i:
                a = j
                b = i
            else:
                a = i
                b = j
            # L’ordre est important, toujours a < b!
            for cle in cache[(a, b)]:  # cache[(a, b)] contient les clés communes aux dicos a et b.
                cle_fn = cle.strip('>')
                if cle_fn not in files:
                    files[cle_fn] = []
                files[cle_fn].append(cle +'\n'+ dico[cle] + '\n' + cle + '\n'+  d[cle])
     
    # Et n’y a plus qu’à écrire tout ça dans les fichiers*:
    for file_name, lines in files.items():
        with open(file_name, "w") as f:
            f.write('\n'.join(lines))
    J’espère que j’ai été assez clair dans mes explications, on est déjà dans du python d’assez bon niveau, là…

  9. #9
    Membre confirmé
    Inscrit en
    Mars 2012
    Messages
    73
    Détails du profil
    Informations forums :
    Inscription : Mars 2012
    Messages : 73
    Par défaut
    Merci beaucoup pour le temps que vous avez consacré à mon problème mont29 , je vais prendre le temps de bien étudier ce code

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

Discussions similaires

  1. [Fortran 95] Fonction au nombre d'arguments variable
    Par Ymkjen dans le forum Fortran
    Réponses: 1
    Dernier message: 12/02/2009, 15h15
  2. nombre des variables dynamique dans une fonction
    Par Abdelkaoui dans le forum C
    Réponses: 10
    Dernier message: 29/02/2008, 15h37
  3. Réponses: 9
    Dernier message: 15/05/2007, 12h41
  4. Fonction Execlp avec nombre parametres variable
    Par laurent_ifips dans le forum C
    Réponses: 3
    Dernier message: 25/11/2005, 20h14
  5. Réponses: 4
    Dernier message: 31/10/2005, 17h48

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