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 :

Occurence de caractères


Sujet :

Python

  1. #1
    Futur Membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Janvier 2019
    Messages
    4
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Janvier 2019
    Messages : 4
    Par défaut Occurence de caractères
    Bonjour, je dois créer une fonction caracteres_occurrences(l) qui retourne un dictionnaire contenant pour chaque caractère dans les différentes chaînes de caractères les indices des chaînes qui contiennent le caractère au moins une fois.

    Par exemple, avec la liste : l = ["ceci n'est pas une pipe", "le fils de l'homme", "golconda"] , la fonction doit me renvoyer le dictionnaire :

    d = {'c': [0,2], 'e': [0,1], 'i': [0,1], ' ': [0,1], 'n': [0,2], "'": [0,1], 's': [0,1], 't': [0], 'p': [0], 'a': [0,2], 'u': [0], 'f': [1], 'l': [1,2], 'd': [1,2], 'h': [1], 'o': [1,2], 'm': [1], 'g': [2]}

    -> le 'c' se retrouve au moins une fois dans l[0] et dans l[2] ; le 'e' se retrouve au moins une fois dans l[0] et dans l[1], ...

    Le problème est qu'avec mon code, la fonction ne me renvoie que le dernier indice de la liste dans lequel le caractère se retrouve :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    def caracteres_occurences(l) :
        d = {}
        long = len(l)
        for i in range (long) :
            for j in l[i] :
                d[j] = [i]
        return d
    => me renvoie : {'c': [2], 'e': [1], 'i': [1], ' ': [1], 'n': [2], "'": [1], 's': [1], 't': [0], 'p': [0], 'a': [2], 'u': [0], 'l': [2], 'f': [1], 'd': [2], 'h': [1], 'o': [2], 'm': [1], 'g': [2]}

    Comment faire pour prendre en compte tous les indices ?

  2. #2
    Expert confirmé
    Avatar de fred1599
    Homme Profil pro
    Lead Dev Python
    Inscrit en
    Juillet 2006
    Messages
    4 869
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations professionnelles :
    Activité : Lead Dev Python
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Juillet 2006
    Messages : 4 869
    Par défaut
    Bonjour,

    Un exemple permettant d'avoir chaque lettre unique d'un mot,

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    >>> s = "ceci n'est pas une pipe"
    >>> letters = set(s)
    >>> letters
    {'a', 'p', 's', 'c', ' ', 'u', 'n', 't', "'", 'e', 'i'}
    Ensuite vous avez un dictionnaire, où vous testez si chaque clé est présente, et si ce n'est pas le cas, à ajouter au dictionnaire.

    P.S Donc dans votre proposition de code, il manque le cas où la lettre est déjà présente dans le dictionnaire, et l'ajouter à votre liste représentant la valeur du dictionnaire.
    En gros vous écrasez la précédente valeur, d'où des listes de taille 1 à chaque fois.

  3. #3
    Expert confirmé Avatar de BufferBob
    Profil pro
    responsable R&D vidage de truites
    Inscrit en
    Novembre 2010
    Messages
    3 041
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : responsable R&D vidage de truites

    Informations forums :
    Inscription : Novembre 2010
    Messages : 3 041
    Par défaut
    salut,

    pour la frime:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    l = ["ceci n'est pas une pipe", "le fils de l'homme", "golconda"]
    d = {i:[j for j in range(len(l)) if i in l[j]] for i in dict.fromkeys(set(''.join(l)), 0)}
    sinon au delà des boucles imbriquées comment/par quel bout/etc. la petite difficulté ici réside dans le fait d'étendre un dictionnaire et/ou une liste

    pour étendre une liste il y a la méthode .append(), pour les dictionnaires c'est différent, on peut se contenter d'assigner une valeur à une nouvelle clé dico[newkey] = newvalue, mais ici le propos est d'incrémenter la valeur, et il va donc falloir tester si la clé existe déjà dans le dictionnaire ou s'il s'agit d'une nouvelle clé à créer

    de manière générale une bonne façon d'appréhender l'algorithme de notre programme est de commencer par faire l'opération à la main, "comment je m'y prendrai (intellectuellement) pour faire ce que fait le programme ?", ce qui permet d'avoir une meilleure idée des étapes à réaliser, dans quel ordre, comment tourner la chose etc.

  4. #4
    Expert confirmé
    Avatar de fred1599
    Homme Profil pro
    Lead Dev Python
    Inscrit en
    Juillet 2006
    Messages
    4 869
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations professionnelles :
    Activité : Lead Dev Python
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Juillet 2006
    Messages : 4 869
    Par défaut
    pour la frime:
    et le zen de python ?

    Par rapport à la solution simple, elle est en plus deux fois moins efficace !

    Simple is better than complex

  5. #5
    Expert confirmé Avatar de BufferBob
    Profil pro
    responsable R&D vidage de truites
    Inscrit en
    Novembre 2010
    Messages
    3 041
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : responsable R&D vidage de truites

    Informations forums :
    Inscription : Novembre 2010
    Messages : 3 041
    Par défaut
    Citation Envoyé par fred1599 Voir le message
    et le zen de python ?
    j'avoue ne l'avoir jamais lu (probablement parce que je ne suis pas développeur et que je me sens pas concerné), et puis le zen de python c'est plutôt quand on veut donner la solution au PO

    à la limite je serais plutôt issu de la sécurité, dans laquelle l'obfuscation de code fait partie des choses assez classiques, ajoute à ça que j'ai toujours été friand de ces bestioles hideuses telles le IOCCC, les one-liners, les quines ou les codes polyglottes, et étrangement je le vis bien

    ce que j'aime là dedans c'est justement la difficulté de créer ce genre de code, c'est pas un gros challenge, mais ça force à une gymnastique mentale qui n'a rien d'intuitif, et ça me plait

    pour autant quand le besoin l'exige je suis capable de pondre du code lisible et consensuel, je suis sûr que ça a même dû m'arriver sur ces forums...

    Citation Envoyé par fred1599 Voir le message
    Par rapport à la solution simple, elle est en plus deux fois moins efficace !
    ah ? je ne me suis pas posé la question en ces termes (c'est pas fait pour), mais j'ai quand même un gros doute, ce serait quoi ton implémentation simple et 2x plus efficace ? (éventuellement en pv)

  6. #6
    Expert confirmé
    Avatar de fred1599
    Homme Profil pro
    Lead Dev Python
    Inscrit en
    Juillet 2006
    Messages
    4 869
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations professionnelles :
    Activité : Lead Dev Python
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Juillet 2006
    Messages : 4 869
    Par défaut
    Je t'envoie ça en MP, je pense que c'est la solution adaptée pour le PO.

  7. #7
    Expert confirmé Avatar de disedorgue
    Homme Profil pro
    Ingénieur intégration
    Inscrit en
    Décembre 2012
    Messages
    4 422
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur intégration
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Décembre 2012
    Messages : 4 422
    Par défaut
    Houla, c'est pas gentil ça, on veut aussi en profiter

    Car comme BufferBob, j'aime bien aussi ces petits codes d'une ligne et la gymnastique intellectuelle qui va avec pour les pondre.

    Mais j'aime bien aussi les codes efficaces et étant "débutant" dans le monde python, je suis preneur d'un exemple aux petits oignons de ce genre de code.

    PS: Bon après, je comprends que tu ne veuilles pas faire le travail à la place du demandeur, donc ne te sent pas obligé de répondre

  8. #8
    Expert confirmé Avatar de BufferBob
    Profil pro
    responsable R&D vidage de truites
    Inscrit en
    Novembre 2010
    Messages
    3 041
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : responsable R&D vidage de truites

    Informations forums :
    Inscription : Novembre 2010
    Messages : 3 041
    Par défaut
    Citation Envoyé par fred1599 Voir le message
    (...)
    anéfé, c'était même presque 3x plus lent en fait, bien vu
    essentiellement dû au fait qu'on ne peut pas faire d'assignation directe à l'intérieur d'une list comprehension, même en essayant de ruser avec update(), __setitem__ et get() je parviens pas à descendre en dessous de 2x le temps. tristesse ineffable.

    Citation Envoyé par disedorgue Voir le message
    Houla, c'est pas gentil ça, on veut aussi en profiter
    ça tiendrait qu'à moi tu t'en doute je le publierai ouvertement avec une sauvagerie mêlée de férocité (©) convaincu que l'apprentissage est une affaire de responsabilité personnelle, et que si on ne veut pas se gâcher le plaisir il suffit de ne pas regarder la solution, mais bon, la phrase "Nous ne sommes pas là pour faire vos exercices" peut éventuellement être interprétée comme une interdiction ou plus simplement un appel à ne pas le faire, dans le doute je cherche pas particulièrement à en éprouver les limites disons...

    au pire je crois me souvenir qu'il y a des balises de spoiler sur ce forum, à vérifier

  9. #9
    Modérateur

    Avatar de Bktero
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2009
    Messages
    4 500
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Juin 2009
    Messages : 4 500
    Billets dans le blog
    1
    Par défaut
    Du code cryptique de BufferBob, il y a quand même un truc à sortir de très intéressant : l'utilisation de join() ! Je voulais justement en parler car je pense que ça serait plus simple de parcourir une chaine qu'une liste de chaine :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    >>> l = ["ceci n'est pas une pipe", "le fils de l'homme", "golconda"]
    >>> w = "".join(l)
    >>> w
    "ceci n'est pas une pipele fils de l'hommegolconda"
    Avec set(), on peut obtenir l'ensemble de caractères présents, comme proposé par fred1559.

    Tout achever tout ça, il faut regarder du côté de count() : il permet de compter les occurrences d'une sous-chaîne dans une chaîne.....et un caractère est une sous-chaîne

    PS : en relisant le titre de la discussion et le message #1, j'ai un peu un doute sur ce qu'il faut faire...

    PS2 : OK, au temps pour moi, ce n'est pas du tout un comptage d'occurences

  10. #10
    Expert confirmé Avatar de disedorgue
    Homme Profil pro
    Ingénieur intégration
    Inscrit en
    Décembre 2012
    Messages
    4 422
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur intégration
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Décembre 2012
    Messages : 4 422
    Par défaut
    Pas de souci, on a échangé...

    Et pour la petite histoire, les liste en compréhension passe en sous main par le modèle objet de python (je simplifie, mais il y a un peu de ça), donc difficile d'avoir les perf de la simple fonction.

  11. #11
    Modérateur

    Avatar de Bktero
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2009
    Messages
    4 500
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Juin 2009
    Messages : 4 500
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par BufferBob Voir le message
    la phrase "Nous ne sommes pas là pour faire vos exercices" peut éventuellement être interprétée comme une interdiction ou plus simplement un appel à ne pas le faire
    Je pense que c'est un appel à ne pas le faire, ou la proclamation du droit à dire aux demandeurs qu'on ne le fera pas. Je ne pense pas que ce soit une interdiction

    Citation Envoyé par BufferBob Voir le message
    au pire je crois me souvenir qu'il y a des balises de spoiler sur ce forum, à vérifier
    Oui oui ! [spoiler]truc à cacher[/spoiler] donne :
    truc à cacher

  12. #12
    Expert confirmé
    Avatar de fred1599
    Homme Profil pro
    Lead Dev Python
    Inscrit en
    Juillet 2006
    Messages
    4 869
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Meurthe et Moselle (Lorraine)

    Informations professionnelles :
    Activité : Lead Dev Python
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Juillet 2006
    Messages : 4 869
    Par défaut
    Citation Envoyé par BufferBob Voir le message
    anéfé, c'était même presque 3x plus lent en fait, bien vu
    essentiellement dû au fait qu'on ne peut pas faire d'assignation directe à l'intérieur d'une list comprehension, même en essayant de ruser avec update(), __setitem__ et get() je parviens pas à descendre en dessous de 2x le temps. tristesse ineffable.
    Et encore avec pypy, je suis 3x plus rapide, et je suppose qu'en utilisant cython, je peux faire un tout petit peu mieux, mais le jeu n'en vaut pas vraiment la chandelle.

    P.S J'ai un tout petit peu plus rapide avec defaultdict.

Discussions similaires

  1. Réponses: 6
    Dernier message: 14/08/2011, 16h37
  2. [Source] Analyser la fréquence d'occurence de caractères
    Par M.Dolly dans le forum Contribuez
    Réponses: 3
    Dernier message: 01/09/2009, 12h23
  3. [TPW] Afficher le nombre d'occurences de caractère
    Par miliassouma6600 dans le forum Turbo Pascal
    Réponses: 5
    Dernier message: 16/05/2009, 13h06
  4. Réponses: 5
    Dernier message: 05/11/2008, 07h43
  5. Remplacement d'occurence de caractères
    Par klingc dans le forum Langage
    Réponses: 26
    Dernier message: 12/09/2008, 16h54

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