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 :

Compréhension de liste


Sujet :

Python

  1. #1
    Membre à l'essai
    Profil pro
    Inscrit en
    Mai 2011
    Messages
    35
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2011
    Messages : 35
    Points : 18
    Points
    18
    Par défaut Compréhension de liste
    Bonjour à tous,
    Je bloque un peu sur un exercice trouvé sur interactivepython (d'ailleurs, est ce que quelqu'un pourrait me confirmer ou infirmer si ce site est bon pour que je puisse devenir un bon programmeur python ET être capable de résoudre efficacement des problèmes algorithmiques complexes).
    Il est assez simple, il faut afficher une liste qui contient tous les caractères présents dans les différents mots d'une chaîne donné. Il est aussi spécifié de le résoudre avec les compréhensions de liste.
    Là ou je sèche, c'est de trouver une expression pour que la liste finale ne puisse pas avoir de doublon!
    Voici la liste de l'exercice: ['cat', 'dog' 'rabbit']. Ce code affiche tous les caractères présents (avec doublon):

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    liste = [word[i] for word in ['cat','dog','rabbit'] for i in range(len(word))]
    Pour supprimer les doublons, j'ai pensé à ajouter à la fin la condition 'if word[i] not in [word[j] for j in range(i)] mais ça ne marche pas vraiment étant donné qu'on ne compare que les lettres répétées au sein du même mots alors qu'elles peuvent être répétées dans différents mots.
    La condition if liste.count(word[i])) ne marche pas non plus.

    C'est évidemment possible de le résoudre (facilement) en transformant la liste en set puis en liste mais je voulais savoir si il n'y avait pas une petite astuce pour résoudre le problème en une seule ligne avec la compréhension des listes.

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

    Voilà comment on pourrait faire:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    liste = ['cat', 'dog' 'rabbit']
     
    cars = ''.join(liste)
    liste2 = [car for i, car in enumerate(cars) if car not in cars[:i]]
     
    print liste2
    ['c', 'a', 't', 'd', 'o', 'g', 'r', 'b', 'i']
    "join" permet d'avoir tous les caractères en ajoutant toutes les chaines. On pourrait rester en type list: "cars = [car for mot in liste for car in mot]"

    "enumerate" permet d'obtenir l'indice du caractère en plus du caractère lui-même. Mais on pourait n'utiliser que l'indice: liste2 = [cars[i] for i in range(0, len(cars)) if cars[i] not in cars[:i]]. C'est seulement moins beau.

    L'astuce consiste à n'ajouter le caractère que s'il n'a pas déjà été trouvé avant: "if car not in cars[:i]".

    C'est un code concis, mais je ne sais pas s'il est efficace: à chaque caractère, on est obligé de construire une nouvelle chaine: cars[:i] pour faire le test.
    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

  3. #3
    Expert éminent

    Homme Profil pro
    Inscrit en
    Octobre 2008
    Messages
    4 300
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations forums :
    Inscription : Octobre 2008
    Messages : 4 300
    Points : 6 780
    Points
    6 780
    Par défaut
    Salut,

    Une autre idée:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    >>> l = ['cat', 'dog' 'rabbit']
    >>> l2 = [c for c in set("".join(l))]
    >>> l2
    ['a', 'c', 'b', 'd', 'g', 'i', 'o', 'r', 't']
    On peut directement convertir le set en list mais puisqu'il faut une list comprehension.

  4. #4
    Membre éprouvé
    Inscrit en
    Août 2010
    Messages
    1 124
    Détails du profil
    Informations forums :
    Inscription : Août 2010
    Messages : 1 124
    Points : 1 277
    Points
    1 277
    Par défaut
    Bonsoir,

    Difficile de battre set("".join(l))! Le unique_everseen de http://docs.python.org/2/library/itertools.html utilise également un set.

    Petite contribution pour join()-> list-comp
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    phrase= ("une", "petite", "phrase")
    # LComp pour aplatir la phrase, plutot que join
    cars=  [uchars.add(lettre) for mot in phrase for lettre in mot]
    # LComp pour unique de Tyrtamos
    liste2 = [car for i, car in enumerate(cars) if car not in cars[:i]]

  5. #5
    Membre à l'essai
    Profil pro
    Inscrit en
    Mai 2011
    Messages
    35
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2011
    Messages : 35
    Points : 18
    Points
    18
    Par défaut
    Bonjour,
    Je vous remercie pour toutes vos réponses.
    Au fait, au début, je pensais que c'était une bonne idée d'essayer de le faire avec la liste compréhension 'uniquement' mais comme l'a très bien remarqué tyrtamos, la solution consistant à construire à chaque fois une liste (pour vérifier s'il n'y a pas eu de doublon) n'est pas forcément optimal et meilleur que les autres. Donc, autant se contenter de la conversion à un ensemble, ce qui résout facilement le problème.

    Encore une fois, merci à tous!

Discussions similaires

  1. Compréhension de listes
    Par Bonker dans le forum Général Python
    Réponses: 4
    Dernier message: 03/11/2013, 18h02
  2. Réponses: 3
    Dernier message: 02/02/2012, 15h55
  3. Liste dynamique compréhension
    Par speedy_g dans le forum Excel
    Réponses: 3
    Dernier message: 01/12/2011, 10h35
  4. compréhension de liste paire par paire
    Par sopsag dans le forum Général Python
    Réponses: 13
    Dernier message: 07/12/2010, 21h36
  5. Syntaxe élégante pour une fusion de compréhension de liste
    Par sopsag dans le forum Général Python
    Réponses: 8
    Dernier message: 23/08/2010, 12h22

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