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 :

Parcourir une liste en yoyo ? [Python 3.X]


Sujet :

Python

  1. #1
    Membre habitué Avatar de LeNarvalo
    Homme Profil pro
    Modder
    Inscrit en
    février 2014
    Messages
    105
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Modder
    Secteur : Santé

    Informations forums :
    Inscription : février 2014
    Messages : 105
    Points : 178
    Points
    178
    Par défaut Parcourir une liste en yoyo ?
    Bonjour (et bonne année) ça fait quelques temps que je n'étais pas venu poser une question à la con...

    Exemple : J'ai un texte = "toto va a la plage" et une liste = ["1","2","3","4","5"] comment obtenir ça : "1t2o3t4o 5v4a 3a 2l1a 2p3l4a5g4e". (Vous voyez l'histoire du yoyo ?)
    J'ai bidouiller un truc qui fait le boulot mais c'est pas beau et surement pas très efficace.

    Passez votre chemin si vous avez d'autres choses plus intéressantes à faire ! Mais je me suis dit que ça prendrait 30 secondes à l'un des pro de ce forum...

    Merci quand même ou désolé pour la perte de temps...

    PS : C'est pour faire de la coloration de texte avec les balises [color=#......]

  2. #2
    Nouveau membre du Club
    Homme Profil pro
    Ingénieur développement matériel électronique
    Inscrit en
    juin 2018
    Messages
    15
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Aube (Champagne Ardenne)

    Informations professionnelles :
    Activité : Ingénieur développement matériel électronique
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : juin 2018
    Messages : 15
    Points : 31
    Points
    31
    Par défaut
    hum, pas réussi en une ligne =P

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    from itertools import cycle, chain
     
    def func(txt, n):
        yoyo = cycle(chain(range(1,n),range(n,1,-1)))
        return ''.join(str(next(yoyo))+x if x != ' ' else x for x in txt)
     
    print(func("toto va a la plage",5))

  3. #3
    Expert éminent
    Avatar de tyrtamos
    Homme Profil pro
    Retraité
    Inscrit en
    décembre 2007
    Messages
    4 037
    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 037
    Points : 8 363
    Points
    8 363
    Billets dans le blog
    6
    Par défaut
    Bonjour,

    Citation Envoyé par LeNarvalo Voir le message
    ...question à la con...
    Je confirme...

    Voilà une solution, pas forcément élégante, mais qui donne le résultat:

    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
    texte = "toto va a la plage"
    liste = ["1","2","3","4","5"]
     
    # obtenir une liste au moins aussi longue que texte
    liste = liste[:-1] + list(reversed(liste))[:-1] # => ['1', '2', '3', '4', '5', '4', '3', '2']
    while len(liste)<len(texte):
        liste += liste
     
    # calcul
    i = 0
    j = 0
    resultat = ""
    while i<len(texte):
        if texte[i]==" ":
            resultat += texte[i] # pas d'ajout pour un espace
        else:
            resultat += liste[j] + texte[i]
            j += 1
        i += 1 # caractère suivant   
     
    print(resultat)
    Ce qui donne bien:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1t2o3t4o 5v4a 3a 2l1a 2p3l4a5g4e
    Ce qui complique le code, c'est que les espaces ne font pas l'objet d'un ajout, sinon, on pourrait faire beaucoup plus simple avec la fonction "zip".
    Un expert est une personne qui a fait toutes les erreurs qui peuvent être faites, dans un domaine étroit... (Niels Bohr)
    Mes recettes python: http://www.jpvweb.com

  4. #4
    Membre habitué Avatar de LeNarvalo
    Homme Profil pro
    Modder
    Inscrit en
    février 2014
    Messages
    105
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Modder
    Secteur : Santé

    Informations forums :
    Inscription : février 2014
    Messages : 105
    Points : 178
    Points
    178
    Par défaut
    Merci à tous les deux !

    Je vais regarder du côté de itertools ce n'est pas vraiment 12345 que je veux insérer mes [color=#......]LETTRE[/color].

    A bientôt pour le prochain épisode !

  5. #5
    Nouveau membre du Club
    Homme Profil pro
    Ingénieur développement matériel électronique
    Inscrit en
    juin 2018
    Messages
    15
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Aube (Champagne Ardenne)

    Informations professionnelles :
    Activité : Ingénieur développement matériel électronique
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : juin 2018
    Messages : 15
    Points : 31
    Points
    31
    Par défaut
    Ah?! Juste remplacer les "range" alors:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    from itertools import cycle
     
    def func(txt, lst):
        yoyo = cycle(lst[:-1]+lst[-1:0:-1])
        return ''.join(next(yoyo)+x if x != ' ' else x for x in txt)
     
    print(func("toto va a la plage",['1','2','3','4','5']))

  6. #6
    Membre confirmé
    Homme Profil pro
    Développeur banc de test
    Inscrit en
    mai 2014
    Messages
    192
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 33
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Développeur banc de test
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : mai 2014
    Messages : 192
    Points : 460
    Points
    460
    Par défaut
    Bonjour,

    j'avais pensé utiliser cycle aussi mais c'est assez simple à faire en fait.

    Pour réaliser le cyclage :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    print(liste + liste[1:-1][::-1])
    >> ['1', '2', '3', '4', '5', '4', '3', '2']

    Il suffit ensuite de faire modulo de l'indice de texte :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    print(", ".join((liste + liste[1:-1][::-1])[i % (2 * len(liste) - 2)] for i, c in enumerate(texte)))
    >> 1, 2, 3, 4, 5, 4, 3, 2, 1, 2, 3, 4, 5, 4, 3, 2, 1, 2

    Ensuite on gère le cas des espaces en comptant le nombre d'espaces restants par rapport au nombre total d'espaces dans texte, ce sera la retenu qu'il faudra ajouter à l'indexation de liste :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    print("".join(str(texte.count(" ") - texte[i + 1:].count(" ")) + c for i, c in enumerate(texte)))
    >> 0t0o0t0o1 1v1a2 2a3 3l3a4 4p4l4a4g4e

    Plus qu'à combiner tout ça :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    print("".join([(liste + liste[1:-1][::-1])[(i - (texte.count(" ") - texte[i + 1:].count(" "))) % (2 * len(liste) - 2)] + c, " "][c == " "] for i, c in enumerate(texte)))
    >> 1t2o3t4o 5v4a 3a 2l1a 2p3l4a5g4e


    Bon par contre si vous insérez un machin de ce genre dans vos codes pensez à commenter.

  7. #7
    Membre habitué Avatar de LeNarvalo
    Homme Profil pro
    Modder
    Inscrit en
    février 2014
    Messages
    105
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Modder
    Secteur : Santé

    Informations forums :
    Inscription : février 2014
    Messages : 105
    Points : 178
    Points
    178
    Par défaut
    Citation Envoyé par YCL-1 Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    print("".join([(liste + liste[1:-1][::-1])[(i - (texte.count(" ") - texte[i + 1:].count(" "))) % (2 * len(liste) - 2)] + c, " "][c == " "] for i, c in enumerate(texte)))
    Bon par contre si vous insérez un machin de ce genre dans vos codes pensez à commenter.
    Nice ! J'aurais jamais pensé à ça (et encore moins réussit).

  8. #8
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    février 2006
    Messages
    8 702
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

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

    Informations forums :
    Inscription : février 2006
    Messages : 8 702
    Points : 23 846
    Points
    23 846
    Billets dans le blog
    1
    Par défaut
    Bonjour
    Citation Envoyé par tyrtamos Voir le message
    Voilà une solution, pas forcément élégante, mais qui donne le résultat:
    Ah, c'est la partie du forum que j'aime: celui où chacun y va de sa petite solution

    Code python : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    def func(txt, n):
    	nb=(tuple(range(1, n+1)) + tuple(range(n-1, 1, -1))) * (len(txt)//n+1)
    	res=""
    	i=0
    	for l in txt:
    		res+="%d%s" % (nb[i], l)
    		if not l.isspace(): i+=1
    	# for
    	return res
    # func()
     
    print(func("toto va a la plage", 5))
    C'est vrai que l'espace à sauter (là j'ai utilisé isspace() et ainsi éliminé tout ce qui était "de type" espace, comme les tabulations) rend difficile de faire ça en une ligne via zip().

    Citation Envoyé par LeNarvalo Voir le message
    Mais je me suis dit que ça prendrait 30 secondes à l'un des pro de ce forum...
    Ca m'a pris quand-même un peu plus de temps (dans les 10mn quoi)...

    Citation Envoyé par YCL-1 Voir le message
    Ensuite on gère le cas des espaces en comptant le nombre d'espaces restants par rapport au nombre total d'espaces dans texte, ce sera la retenu qu'il faudra ajouter à l'indexation de liste
    Ouais je suis allé au plus simple: je génère le "yoyo" comme étant de longueur égale au texte de base, sans me préoccuper des espaces. Il peut être alors plus long que nécessaire mais je considère que c'est peanut (dans ma première version j'avais même écrit *n ce qui générait un yoyo de n cycles).

    Sinon bravo à Daguhh pour sa solution à base d'itertools et chain. Jolie maitrise de ces librairies
    Mon Tutoriel sur la programmation «Shell»
    Sinon il y en a pleins d'autres. N'oubliez pas non plus les différentes faq disponibles sur ce site

  9. #9
    Expert confirmé
    Avatar de fred1599
    Homme Profil pro
    Développeur python
    Inscrit en
    juillet 2006
    Messages
    3 060
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations professionnelles :
    Activité : Développeur python
    Secteur : Santé

    Informations forums :
    Inscription : juillet 2006
    Messages : 3 060
    Points : 5 754
    Points
    5 754
    Par défaut
    Peut-être un peu moins cryptique, histoire de goût on va dire,

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    def func(txt, lst):    
        yoyo = cycle(lst + lst[::-1][1:-1])
        return ''.join(next(yoyo) + x if x != ' ' else x for x in txt)
    Celui qui trouve sans chercher est celui qui a longtemps cherché sans trouver.(Bachelard)
    La connaissance s'acquiert par l'expérience, tout le reste n'est que de l'information.(Einstein)

  10. #10
    Nouveau membre du Club
    Homme Profil pro
    Ingénieur développement matériel électronique
    Inscrit en
    juin 2018
    Messages
    15
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Aube (Champagne Ardenne)

    Informations professionnelles :
    Activité : Ingénieur développement matériel électronique
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : juin 2018
    Messages : 15
    Points : 31
    Points
    31
    Par défaut
    histoire de goût on va dire,
    Je sais pas sil 'analogie est parlante, mais je préfère assembler comme ça :
    Que comme ça:
    Et oui, j'imagine qu'inverser et slicer en deux temps est plus parlant. Un compromis? =P
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    lst[:-1] + lst[::-1][:-1]
    rend difficile de faire ça en une ligne via zip().
    en comptant le nombre d'espaces
    pour sa solution à base d'itertools
    Voici pour la solution : on supprime les espaces, on zippe, on remet les espaces. (Et on ajoute du functools!)
    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
    >>> from itertools import cycle, accumulate
    >>> from functools import reduce
    >>> 
    >>> texte = "toto va a la plage"
    >>> liste = ["1","2","3","4","5"]
    >>> 
    >>> lettres = [''.join(x) for x in zip(cycle(liste[:-1]+liste[:0:-1]),texte.replace(' ',''))]
    >>> lettres
    ['1t', '2o', '3t', '4o', '5v', '4a', '3a', '2l', '1a', '2p', '3l', '4a', '5g', '4e']
    >>> 
    >>> indices = list(accumulate([len(x)+1 for x in texte.split(' ')], initial=-1))[1:-1]
    >>> indices
    [4, 7, 9, 12]
    >>> 
    >>> ''.join(reduce(lambda x,y : x[:y] + [' '] + x[y:], indices, lettres))
    '1t2o3t4o 5v4a 3a 2l1a 2p3l4a5g4e'
    >>>
    Soit l'expression en "une ligne":
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    from itertools import cycle, accumulate
    from functools import reduce
     
    texte = "toto va a la plage"
    liste = ["1","2","3","4","5"]
     
    ''.join(reduce(lambda x,y : x[:y] + [' '] + x[y:], list(accumulate([len(x)+1 for x in texte.split(' ')], initial=-1))[1:-1], [''.join(x) for x in zip(cycle(liste[:-1]+liste[:0:-1]),texte.replace(' ',''))]))

  11. #11
    Expert éminent
    Avatar de tyrtamos
    Homme Profil pro
    Retraité
    Inscrit en
    décembre 2007
    Messages
    4 037
    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 037
    Points : 8 363
    Points
    8 363
    Billets dans le blog
    6
    Par défaut
    Bonjour,

    Je suis toujours impressionné par les problèmes compliqués qu'on peut résoudre en une seule ligne en Python, et il m'arrive aussi d'y prendre plaisir.

    Il reste que ce n'est pas toujours une bonne solution, au moins pour deux raisons:

    - c'est rapidement illisible, et il faudra faire un gros effort pour se rappeler ce que ça fait dans 6 mois. Et dans une entreprise, les programmeurs qui font ça sont rapidement pris pour des gens dangereux, parce que personne ne peut reprendre leurs codes une fois qu'ils sont partis.

    - les quelques tests que j'ai fait sur le sujet m'ont montré que le code Python très concis n'est pas forcément plus rapide.

    Il reste que c'est très amusant...
    Un expert est une personne qui a fait toutes les erreurs qui peuvent être faites, dans un domaine étroit... (Niels Bohr)
    Mes recettes python: http://www.jpvweb.com

  12. #12
    Nouveau membre du Club
    Homme Profil pro
    Ingénieur développement matériel électronique
    Inscrit en
    juin 2018
    Messages
    15
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Aube (Champagne Ardenne)

    Informations professionnelles :
    Activité : Ingénieur développement matériel électronique
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : juin 2018
    Messages : 15
    Points : 31
    Points
    31
    Par défaut
    Oui, on est d'accord, c'est pour le fun.

    je ne considère "solution" du msg #10 :
    - ni optimale : elle génère des objets en mémoire qui vont peser lourd dès que le texte grandi un peu
    - ni élégante : oui, c'est parfaitement illisible et indébogable

    Bon, elle permet au moins de placer la fonction zip à laquelle on pense spontanément pour des problèmes du type.

    Ensuite, au-delà de créer des instructions plus compactes, les listes intention ça peut permettre de travailler avec des itérables uniquement

  13. #13
    Futur Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    avril 2017
    Messages
    10
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Charente Maritime (Poitou Charente)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Enseignement

    Informations forums :
    Inscription : avril 2017
    Messages : 10
    Points : 9
    Points
    9
    Par défaut generateurs
    Bonjour,

    Même si le sujet est résolu je me suis prêté au jeu pour le fun également avec une solution utilisant un generateur :

    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
     
    from collections import deque
     
    def gen_number():
        numbers = deque([1,2,3,4,5])
        iteration = 0
        while True:
            if iteration == len(numbers):
                numbers.reverse()
                iteration = 0
            num = numbers[0]
            yield num
            iteration +=1
            numbers.rotate(-1)
     
     
    phrase = "toto va a la plage"
     
    yoyo = []
    numbers = gen_number()
     
    for w in phrase:
        if not w.isspace():
            num = next(numbers)
            yoyo.append(f"{num}{w}")
        else:
             yoyo.append(w)
     
    yoyo = "".join(yoyo)
     
    print(yoyo)

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

Discussions similaires

  1. Parcourir une liste de fichiers
    Par viny dans le forum Langage
    Réponses: 3
    Dernier message: 10/01/2007, 18h21
  2. Parcourir une liste de checkbox
    Par fet dans le forum ASP
    Réponses: 3
    Dernier message: 25/07/2006, 13h35
  3. Parcourir une liste deroulante
    Par brandon dans le forum Général JavaScript
    Réponses: 9
    Dernier message: 17/02/2005, 20h03
  4. parcourir une liste de la fin vers le début
    Par zdra dans le forum SL & STL
    Réponses: 12
    Dernier message: 06/02/2005, 19h40
  5. [langage] Parcourir une list de array
    Par nledez dans le forum Langage
    Réponses: 4
    Dernier message: 08/11/2004, 18h11

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