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 :

Parcours de listes, problème d'algo


Sujet :

Python

  1. #1
    Membre confirmé
    Profil pro
    Inscrit en
    Janvier 2012
    Messages
    96
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2012
    Messages : 96
    Par défaut Parcours de listes, problème d'algo
    Bonsoir,

    je suis bloqué sur un algo depuis le début de l'après midi, je dois reconnaître que je suis à cours d'idée

    Voilà ma problématique:

    je dispose d'une liste contenant un grand nombre de lettres (100k environ) ainsi que de deux listes (debut et fin) contenant des positions relatives à ma grandes listes.

    par exemple :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    texte = ['A','B','C'..............................................................,'K']
     
    debut = ['15','2','50']
    fin = ['18','6','61']
    debut[0] et fin[0] sont liés ect..

    Ce que je voudrai, c'est parcourir toute ma liste, et lorsque je tombe dans l'intervalle de debut : fin, je ne touche à rien, sinon je remplace toutes mes lettres hors de cet intervalle par un caractère (peu importe lequel).

    Je veux donc modifier toutes les lettres de ma liste texte qui ne sont pas comprises dans les intervalles de debut et fin.

    Voila ce que j'ai fais pour le moment

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    while (t!=len(texte)):         
    	for i,j,k in zip(debut,fin,texte):
    			if (t> debut) and (t < fin): #si la position actuelle est comprise dans l'intervalle, ne rien faire
                                    t +=1
    				pass
    			else:
    				k = "*"
                                    t+=1
    La taille de mes listes debut / fin est de 100, alors que mon texte est de taille 100 000 (pour 100 000 caractères), mon itération est donc mauvaise, mais je ne vois pas comment procéder.

  2. #2
    Membre extrêmement actif
    Avatar de Golgotha
    Homme Profil pro
    Full-stack Web Developer
    Inscrit en
    Août 2007
    Messages
    1 387
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Full-stack Web Developer
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2007
    Messages : 1 387
    Billets dans le blog
    1
    Par défaut
    Bonjour,

    Voici un exemple qui pourra t'aider :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    texte = ['A','A','A','A','A','A','A','A','A','A','A','A','A','A','A','A','A','A','A','A','A','A','A','A','A','A','A','A'];
    debut = [2,10,20];
    fin = [4,12,22];
     
    t=0;
    while (t!=len(texte)):
    	print t;
    	t=t+1;
    	for i in range(len(debut)):
    		if debut[i] < t < fin[i] :
    			print "dans l'interval";
    Consultant et développeur full-stack spécialiste du Web
    faq jQuery - règles du forum - faqs web

  3. #3
    Expert éminent
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 715
    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 715
    Par défaut
    Salut,
    Déjà, c'est pas trop clair dès:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    debut = ['15','2','50']
    fin = ['18','6','61']
    Pourquoi des chaines de caractères plutôt que des entiers?
    Je comprends que la chose peut être lue comme comme une suite d'intervalles, i.e. (15, 18), (2, 6), (50,61)
    Est ce que ces intervalles sont "disjoints" ou peuvent se chevaucher?

    Posons "disjoints".
    On peut les ranger par ordre croissant:
    (15, 18), (2, 6), (50,61) ==> (2, 6), (15, 18), (50,61)
    On peut extraire les segments qu'on souhaite préserver:
    • (2, 6, les caractères de 2 a 6)
    • (15, 18, ...)
    • (50,61, ...)

    Si l'ancienne liste est L et 'X' le caractère d'effacement, la nouvelle liste c'est: NL = [ 'X' ] * len(L) puis on remet la valeur des segments.
    for s, e, v in segments:
    NL[s:e] = v
    Je ne sais pas quel sera le nombre de caractères de la réunion des différents segments s'il est "petit" envisager une liste creuse: on garde la liste des segments et le caractère de "bourrage".
    Faire que ces informations ressemblent à une liste n'est pas "impossible" mais un travail conséquent qui n'a d'intérêt qu'en fonction des utilisations que vous pourrez faire de l'objet.
    Cordialement,
    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  4. #4
    Membre confirmé
    Profil pro
    Inscrit en
    Janvier 2012
    Messages
    96
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2012
    Messages : 96
    Par défaut
    Bonsoir,

    merci pour vos réponses,

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    texte = ['A','A','A','A','A','A','A','A','A','A','A','A','A','A','A','A','A','A','A','A','A','A','A','A','A','A','A','A'];
    debut = [2,10,20];
    fin = [4,12,22];
     
    t=0;
    while (t!=len(texte)):
    	print t;
    	t=t+1;
    	for i in range(len(debut)):
    		if debut[i] < t < fin[i] :
    			print "dans l'interval";
    Merci pour cet exemple, je comprends pourquoi mon compteur n'était pas efficace, cependant quelque chose m'échappe, je ne vois pas où peut se faire l'itération sur les lettres de "texte", car je ne peux pas le faire dans la boucle for (car les listes ne sont pas de mêmes tailles) et si j'itère après ma boucle for je me retrouve avec un trop grand nombre d'itérations


    Pourquoi des chaines de caractères plutôt que des entiers?
    En fait ces données sont stockées indépendamment dans des fichiers texte, j'ai jugé bon de récupérer les valeurs et de les stocker dans une liste. Je ne suis pas sur d'avoir répondu à la question.

    Est ce que ces intervalles sont "disjoints" ou peuvent se chevaucher?
    En effet les intervalles sont disjoints.

    Je ne sais pas quel sera le nombre de caractères de la réunion des différents segments
    La taille des segments est assez variable, entre 10 et plusieurs milliers de caractères.

    Merci pour vos conseils, je vais travailler tout ça dès demain matin.

    Bonne soirée à vous

  5. #5
    Expert éminent
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 715
    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 715
    Par défaut
    Salut,

    Citation Envoyé par RTK45 Voir le message
    Merci pour cet exemple, je comprends pourquoi mon compteur n'était pas efficace, cependant quelque chose m'échappe, je ne vois pas où peut se faire l'itération sur les lettres de "texte"
    Mouais... alors... avec d'un côté une liste et de l'autre des segments, si pour récupérer les "tranches" de la liste correspondants, on s'amuse à parcourir la liste caractère par caractère puis vérifier si sa position est dans un segment, puis le stocker... fatigue!

    Juste pour faire "joli", on peut créer les fonctions decouper et assembler et raconter la chose ainsi:

    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
    def decouper(liste, segments):
        rc = []    
        for s, t in segments:
            rc.append ([s, t, liste[s:t]])
        return rc
     
    def assembler(tranches, longueur, bourrage='*'):
        nl = [ bourrage ] * longueur
        for s, t, v in tranches:
            nl[s:t] = v
        return nl
     
    if __name__ == '__main__':
        import string
        # les variables d'entrees
        L = list(string.ascii_uppercase)
        S = (2, 4), (10, 12), (20,22)
     
        tranches = decouper(L, S)
        print (tranches)
        nl = assembler(tranches, len(L))
        print (nl)
    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  6. #6
    Membre confirmé
    Profil pro
    Inscrit en
    Janvier 2012
    Messages
    96
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2012
    Messages : 96
    Par défaut
    Merci pour votre solution, je l'ai adapté à mon problème et ça fonctionne très bien. J'aimerai vous poser quelques questions sur le code car je ne suis pas sur d'avoir tout intégré.

    Tout d'abord concernant la fonction assembler:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    def assembler(tranches, longueur, bourrage='*'):
        nl = [ bourrage ] * longueur
        for s, t, v in tranches:
            nl[s:t] = v
        return nl
    La 1ère ligne de la fonction remplie l'intégralité de la liste avec le caractère de bourrage (enfin c'est ce que j'ai compris), puis on remplace les intervalles de la liste par leurs fragments correspondants (si je suis toujours ).

    Ensuite dans le main :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    if __name__ == '__main__':
        import string
        # les variables d'entrees
        L = list(string.ascii_uppercase)
        S = (2, 4), (10, 12), (20,22)
     
        tranches = decouper(L, S)
        print (tranches)
        nl = assembler(tranches, len(L))
        print (nl)
    Je comprends ce qui se passe, néanmoins je m'attendais à ce qu'il faille redéfinir "bourrage" lorsque l'on appel la fonction assembler. Elle est définit avec 3 arguments à la base mais on l'utilise avec seulement 2, je suppose que comme l'argument bourrage est "fixé", Python l'appelera automatiquement. (Je ne suis pas sur de moi).

    Enfin une question bète, j'ai décidé de stocker mes combinaisons dans un tuple (comme dans votre exemple), cependant les valeurs de mes tuples sont entourés de simples quotes, et j'ai dû passé par un
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
     sed "s/'//g" mon_fichier_de_tuples
    pour les éliminer afin que le code tourne, voici comment j'ai crée mon tuple (si vous avez des remarques / conseils):

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    segment = ()
    segments = ()
    for i,j in zip(debut,fin):
     
    	segment = i,j
    	segments += segment,(i,j)
    Ce qui me génère :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    (('79439', '79464'), ('79439', '79464'), ('9155', '9946'), ('9155', '9946'),...
    Je suis conscient que c'est moche, étant donné que tout est doublé, mais comme dans mon cas un doublon de position n'a pas d'influence sur le déroulement du programme, je me contente de ça pour le moment

  7. #7
    Expert éminent
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 715
    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 715
    Par défaut
    Salut,
    La 1ère ligne de la fonction remplie l'intégralité de la liste avec le caractère de bourrage (enfin c'est ce que j'ai compris), puis on remplace les intervalles de la liste par leurs fragments correspondants
    Tout à fait.

    Je comprends ce qui se passe, néanmoins je m'attendais à ce qu'il faille redéfinir "bourrage" lorsque l'on appel la fonction assembler
    Lorsqu'on écrit:
    def assembler(tranches, longueur, bourrage='*'):
    on dit qu'assembler à 3 arguments.
    Le dernier "bourrage" ayant une valeur par défaut peut être "omis" par l'appelant: l'interpréteur sait quoi faire dans ce cas.

    Je suis conscient que c'est moche, étant donné que tout est doublé,
    Hmmm... Python n'est un langage de programmation et le script ne fera que ce qui a été tapé par vos doigts!!
    si vous écrivez:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    	segment = i,j
    	segments += segment,(i,j)
    cela équivaut à segments += (i,j), (i,j) et donc "tout est doublé".
    Et si ce n'est pas ce que vous voulez "don't do that"!

    La vraie question est pourquoi ne pas utiliser simplement le retour de 'zip'?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
        debut, fin = (2, 10, 20), (4, 12, 22)
        print (list(zip(debut, fin)))
    suffit pour transformer les listes debut, fin en une liste de segments...

    cependant les valeurs de mes tuples sont entourés de simples quotes, et j'ai dû passé par un
    12 est un entier
    '12' est une chaîne de caractères.
    Les '' ne font pas partie de la chaine de caractère.
    Ils sont la pour indiquer "chaine de caractères" 12 lorsqu'on fait "print" de l'objet.

    Pour transformer un objet chaîne de caractère (str) qui représente un entier en un objet entier (int) auquel sera assignée la valeur de cet entier... Il faut fabriquer l'objet int à partir de... Exemple:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    chaine = '12'
    valeur  = int(chaine)
    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  8. #8
    Membre averti
    Homme Profil pro
    Inscrit en
    Août 2011
    Messages
    46
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Août 2011
    Messages : 46
    Par défaut
    Coucou,

    Concernant ta question :
    Je comprends ce qui se passe, néanmoins je m'attendais à ce qu'il faille redéfinir "bourrage" lorsque l'on appel la fonction assembler. Elle est définit avec 3 arguments à la base mais on l'utilise avec seulement 2, je suppose que comme l'argument bourrage est "fixé", Python l'appelera automatiquement. (Je ne suis pas sur de moi).
    En effet, ta fonction comprend bien 3 arguments mais à un argument qui à une valeur par défault. Par conséquent, si tu as l'appels par la suite uniquement avec les deux autres arguments qui eux sont nécessaire (pas de valeur par défault), celà fonctionneras.
    Tu peux trouver la répose ici au 4.7 : http://docs.python.org/py3k/tutorial...ning-functions
    The most useful form is to specify a default value for one or more arguments. This creates a function that can be called with fewer arguments than it is defined to allow.
    EDIT : pris de vitesse par wiz ... Par contre il manque une parenthèse de fermeture Mr dans votre exemple

  9. #9
    Expert éminent
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 715
    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 715
    Par défaut
    Citation Envoyé par BUENO
    Par contre il manque une parenthèse de fermeture Mr dans votre exemple
    Ah ben cut&paste a encore frappé, c'est corrigé. Merci
    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  10. #10
    Membre confirmé
    Profil pro
    Inscrit en
    Janvier 2012
    Messages
    96
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2012
    Messages : 96
    Par défaut
    Merci beaucoup pour tous ces compléments, j'y vois beaucoup plus clair et j'ai pu améliorer mon code

    Bonne journée

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

Discussions similaires

  1. [WD18] Problème Parcours de Liste
    Par darkside1993 dans le forum WinDev
    Réponses: 2
    Dernier message: 24/04/2013, 14h02
  2. Réponses: 4
    Dernier message: 08/12/2006, 11h15
  3. Petit problème d'algo
    Par RodEpsi dans le forum Delphi
    Réponses: 5
    Dernier message: 01/08/2006, 15h30
  4. [liste] Problème de tri rapide
    Par sorry60 dans le forum C
    Réponses: 12
    Dernier message: 03/05/2006, 12h16
  5. un petit problème d'algo
    Par supertramp dans le forum Algorithmes et structures de données
    Réponses: 22
    Dernier message: 12/10/2004, 20h13

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